LINUX.ORG.RU

c++, блокировка boost::shared_mutex

 ,


0

1

Имеем два варианта заблокировать шаред мьютекс. Поток блокирует мьютекс на запись, а основной поток пытается получить блокировку на чтение.

1. пробуем заблокировать через try_lock. всегда res==true

#include <boost/thread/shared_mutex.hpp>
#include <mutex>

boost::shared_mutex shared_mtx;
std::mutex mtx;

void thread_fn()
{
	shared_mtx.lock_upgrade();
	mtx.unlock();
	while (true) {
	}
}

void main() {
	mtx.lock();
	std::thread t(thread_fn);
	bool res=shared_mtx.try_lock_shared();
	t.join();
}
2. пытаемся заблокировать с ограничением по времени. тут res==false
#include <boost/thread/shared_mutex.hpp>
#include <mutex>

boost::shared_mutex shared_mtx;
std::mutex mtx;

void thread_fn()
{
	shared_mtx.lock_upgrade();
	mtx.unlock();
	while (true) {
	}
}

void main() {
	mtx.lock();
	std::thread t(thread_fn);
	bool res=shared_mtx.timed_lock(boost::get_system_time() + boost::posix_time::milliseconds(10)); 
	t.join();
}

так и должно быть или это баг такой?


У тебя всё в корне неправильно. Мьютексы не могут блокироваться одним потоком, а разблокироваться другим:

void unlock();

Unlocks the mutex. The mutex must be locked by the current thread of execution, otherwise, the behavior is undefined.

Кроме того, вручную эти функции вызываются только по необходимости.

asaw ★★★★★
()
Ответ на: комментарий от asaw
#include <boost/thread/shared_mutex.hpp>

boost::shared_mutex shared_mtx;

void thread_fn()
{
	shared_mtx.lock_upgrade();
	
	while (true) {
	}
}

void main() {
	std::thread t(thread_fn);
	bool res=shared_mtx.timed_lock(boost::get_system_time() + boost::posix_time::milliseconds(10)); 
	t.join();
}
lsv
() автор топика
Ответ на: комментарий от asaw

а зачем? смысл в том, что мьютекс одним потоком блокируется на запись, а второй пробует его заблокировать на чтение. и должен второй получить false, потому что «1 писатель, много читателей». но с этим мьютексом такое не прокатывает.

lsv
() автор топика
Ответ на: комментарий от lsv

Во-первых не так. Ты одним потоком пытаешься получить upgradable ownership (и, как видно, получаешь), а вторым - exclusive ownership.

asaw ★★★★★
()
Ответ на: комментарий от asaw

так. вот сейчас не понятно было. вот поток не блокирует для записи?


void thread_fn()
{
	shared_mtx.lock_upgrade();
	while (true) {
	}
}

lsv
() автор топика
Ответ на: комментарий от lsv

«Блокирует для записи» <=> «exclusive ownership». Когда у потока есть такая блокировка, то никто кроме этого потока не может не только писать, но и читать (поэтому и exclusive). Upgradable ownership - это нечто между shared ownership и exclusive ownership: http://www.boost.org/doc/libs/1_61_0/doc/html/thread/synchronization.html#thr... В любом случае если у кого-то есть такая блокировка, то exclusive ownership кто-то другой получить не сможет.

asaw ★★★★★
()
Последнее исправление: asaw (всего исправлений: 1)
Ответ на: комментарий от asaw

отлично. не может. но вопрос был в том, что первый вариант как раз таки не может получить блокировку, а второй вариант (с timed_lock) вполне себе получает.

lsv
() автор топика
Ответ на: комментарий от lsv

Потому что кто первый, того и тапки. В первом случае второй поток не успевает стартовать, а во втором случае - стартует быстрее, чем инициализируются соответствующие таймеры.

asaw ★★★★★
()
Ответ на: комментарий от asaw

ты посмотри вниметельно на самый первый пример. там mtx.lock();. он то как раз и не дает основному потоку выполнить try_lock/try_lock_shared пока второй поток не заблокирет шаред мьютекс .

lsv
() автор топика

Тред не читал, но тебе нужно std::conditional_variable.

UVV ★★★★★
()
Ответ на: комментарий от asaw

это да. это я в примере тупанул

lsv
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.