
please wait
|
|
... condition variables have one "feature" which is a common source of bugs: a wait on a condition variable may return even if the condition variable has not been notified. This is called a spurious wake. Spurious wakes cannot be predicted: they are essentially random from the user's point of view. However, they commonly occur when the thread library cannot reliably ensure that a waiting thread will not miss a notification. Since a missed notification would render the condition variable useless, the thread library wakes the thread from its wait rather than take the risk. ... Spurious wakes can cause some unfortunate bugs, which are hard to track down due to the unpredictability of spurious wakes. These problems can be avoided by ensuring that plain wait() calls are made in a loop, and the timeout is correctly calculated for timed_wait() calls. If the predicate can be packaged as a function or function object, using the predicated overloads of wait() and timed_wait() avoids all the problems. - Anthony Williams |
void wait(unique_lock<mutex>& lock); ... The function will unblock when signaled by a call to notify_one() or a call to notify_all(), or spuriously. - IS |
|
|
The thread that intends to modify the variable has to 1. acquire a std::mutex (typically via std::lock_guard) 2. perform the modification while the lock is held 3. execute notify_one or notify_all on the std::condition_variable (the lock does not need to be held for notification) Even if the shared variable is atomic, it must be modified under the mutex in order to correctly publish the modification to the waiting thread. Any thread that intends to wait on std::condition_variable has to 1. acquire a std::unique_lock<std::mutex>, on the same mutex as used to protect the shared variable 2. execute wait, wait_for, or wait_until. The wait operations atomically release the mutex and suspend the execution of the thread. 3. When the condition variable is notified, a timeout expires, or a spurious wakeup occurs, the thread is awakened, and the mutex is atomically reacquired. The thread should then check the condition and resume waiting if the wake up was spurious. |