A condition variable should always be associated with some condition that you should check:
unique_lock <mutex> lck (m);
while (! something )
cv.wait (lck);
The condition is checked while holding the mutex, therefore it is implied that the mutex must protect the data associated with the condition, so you know that it will not change between testing and waiting.
The while
test is not just an if
, because some implementations of variable conditions (including those based on pthreads) may wake up falsely, i.e. when no one has signaled this, so you should check the condition in a loop and repeat, wait until it is. There wait
overload, which takes a predicate and automatically processes false awakenings, waiting for the predicate to return true, for example. here the above example is modified to use a lambda that checks the condition:
unique_lock <mutex> lck (m);
cv.wait (lck, [&] {return something ;});
(In simple cases, I found that an explicit while
easier to read.)
The condition variable used can be thought of as a 3-tuple consisting of a condition variable, a mutex and a predicate, which are conceptually related to each other, using together to wait for the condition variable. All parallel expectations for an object of a variable of a certain condition must use the same mutex and, as a rule, also expect the same predicate (or related predicate, which depends on the same data protected by the same mutex.)
source share