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);
}
}
versus
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);
}
Is there an impact if I omit the lock before calling cond.notify_one() ?
The C++11 standard does not state any requirement for notify_one
and notify_all
; so not holding the lock when you signal a condition_variable is fine. However, it's often necessary for the signaling thread to hold the lock until it sets the condition checked by the waiting thread after it's woken up. If it does not, the program may contain races. For an example, see this SO question: Boost synchronization.
When thread2
is waking, it will attempt to re-aquire the lock. If thread1
is holding the lock, thread2
will block until thread1
releases the lock.
In the code shown here, this doesn't significantly impact behavior. If you were to add any behavior in thread1
after cond.notify_one();
, that behavior would be guaranteed to execute before thread2
proceeds in the second code block only.
Alternatively, you could construct the unique lock in thread2
before entering the for loop, rather than just before waiting on the condition variable. This would ensure that thread1
blocks when trying to construct its own unique lock until thread2
is waiting for a signal, provided that thread1
is not executing before thread2
has initialized itself and entered the loop. This would allow you to guarantee that thread1
doesn't send any notifications that thread2
isn't waiting for.