Consider the following 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 proceed data proceed modified without using a mutex, after which the notification is sent to the condition variable. But it is possible that at the moment the notification is sent, the stream t does not wait on cv : instead, it is inside hardWork() , checking proceed immediately before that and finding it false. Notification skipped. When t completes hardWork , it will resume the wait (presumably forever).
If the main thread blocked the mutex before changing the proceed general data, the situation could have been avoided.
I think this means the situation when you say: "Even if the general variable is atomic, it must be modified under the mutex in order to correctly publish the modification of the waiting thread."
source share