Search code examples
multithreadingc++11memory-model

C++11 reading a bool concurrently


When I have a std::condition_variable cond and some bool flag I can wait for it using a predicate:

cond.wait_for(some_lock, std::chrono::milliseconds(100), { return flag; })

Now I am wondering: Technically C++ only got a proper multi threaded memory model in C++11, and accessing the flag variable in a multi threaded context is basically undefined. So I should have to declare it std::atomic<bool> to escape that undefined behavior, right?

I am specifically wondering: If I'm NOT declaring it std::atomic, can it be that I read stale values from flag all the time as the update never makes it to main memory? Or is this a case of "theoretically yes, but practically never happens"?


Solution

  • Technically C++ only got a proper multi threaded memory model in C++11, and accessing the flag variable in a multi threaded context is basically undefined.

    Accessing a thread-shared variable in C++ is well defined as long as there are no data races. See Threads and data races for more details:

    ... in particular, release of a std::mutex is synchronized-with, and therefore, happens-before acquisition of the same mutex by another thread, which makes it possible to use mutex locks to guard against data races.


    Mutex lock/unlock constitute acquire/release memory barriers. You do not need std::atomic for thread-shared state that is only accessed when the mutex is locked. When a condition notification is received it first locks the mutex, so that you can access the shared state safely.


    People often introduce data races when they try to use std::atomic variables with std::mutex/std::condition_variable and access that std::atomic without holding the mutex. An example.