2012-02-02 4 views
3
boost::condition_variable cond; 
boost::mutex mut; 

//thread1 
{ 
"read_socket()" 
cond.notify_one(); 
} 

//thread2 
{ 
for(;;) 
{ 
... 
boost::unique_lock<boost::mutex> lock(mut); 
cond.wait(lock); 
} 
} 

противповышение :: condition_variable и замок

boost::condition_variable cond; 
boost::mutex mut; 

//thread1 
{ 
"read_socket()" 
boost::unique_lock<boost::mutex> lock(mut); 
cond.notify_one(); 
} 

//thread2 
{ 
for(;;) 
{ 
... 
boost::unique_lock<boost::mutex> lock(mut); 
cond.wait(lock); 
} 

Есть ли влияние, если я опускаю блокировку перед вызовом cond.notify_one()?

+0

'cond.wait (lock)' может возобновиться перед вызовом 'notify_one()'. Вы всегда должны «ждать» в цикле, каждый раз проверяя * условие * (или используйте перегрузку, которая берет предикат). –

ответ

3

В стандарте C++ 11 не указаны требования к notify_one и notify_all; поэтому не удерживая блокировку, когда вы сигнализируете условие_вариабел, это нормально. Тем не менее, часто необходимо, чтобы сигнальный поток удерживал блокировку до тех пор, пока он не установит условие, проверенное ожидающим потоком после того, как он проснулся. Если это не так, программа может содержать гонки. Например, см. Этот вопрос SO: Boost synchronization.

+0

все в порядке, это звучит хорошо, спасибо. – Guillaume07

+1

Однако кажется, что использование блокировки вызовом wait бесполезно, поскольку оно используется только в ожидании – Guillaume07

2

Когда thread2 просыпается, он попытается перезагрузить замок. Если thread1 удерживает замок, thread2 будет блокироваться до thread1 освобождает замок.

В приведенном здесь коде это не оказывает существенного влияния на поведение. Если вы добавили какое-либо поведение в thread1 после cond.notify_one();, это поведение будет гарантировано выполнить до того, как thread2 будет действовать только во втором кодовом блоке.

В качестве альтернативы вы можете построить уникальный замок в thread2 перед вводом цикла for, а не только перед ожиданием переменной условия. Это обеспечило бы блокировку thread1 при попытке построить свой собственный уникальный замок до тех пор, пока thread2 не ждет сигнала, если thread1 не выполняется до того, как thread2 инициализировал себя и ввел в цикл. Это позволит вам гарантировать, что thread1 не отправит никаких уведомлений, которые thread2 не ждет.

Смежные вопросы