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"?
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.