Reputation:
I am reading about std::condition_variable on http://en.cppreference.com/w/cpp/thread/condition_variable and I don't understand this:
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.
Why a shared atomic variable is not properly published if it is not modified under mutex? How to understand this statement?
On another page http://en.cppreference.com/w/cpp/atomic/atomic there is a statement that seems to contradict to the the first statement:
If one thread writes to an atomic object while another thread reads from it, the behavior is well-defined (see memory model for details on data races)
Upvotes: 30
Views: 5108
Reputation: 10336
Consider this example:
std::atomic_bool proceed(false);
std::mutex m;
std::condition_variable cv;
std::thread t([&m,&cv,&proceed]()
{
{
std::unique_lock<std::mutex> l(m);
while(!proceed) {
hardWork();
cv.wait(l);
}
}
});
proceed = true;
cv.notify_one();
t.join();
Here the atomic shared data proceed
is modified without the use of a mutex, after which notification is sent to the condition variable. But it is possible that at the instant that the notification is sent, the thread t
is not waiting on cv
: instead it is inside hardWork()
having checked proceed
just before that and found it to be false. The notification is missed. When t
completes hardWork
, it will resume the wait (presumably forever).
Had the main thread locked the mutex before modifying the shared data proceed
, the situation would have been avoided.
I think this is the situation in mind when saying "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."
Upvotes: 40