Condition variables are generally used such that the state they refer to is modified under a mutex. However, when the state is just a single set-only flag, there's no need for a mutex to prevent simultaneous execution. So one might want to do something like this:
flag = 1;
pthread_cond_broadcast(&cvar);
However, this is only safe if pthread_cond_broadcast
implies a write memory barrier; otherwise, the waiting thread may see the condition variable broadcast before the flag write. That is, the waiting thread may awaken, consume the cvar signal, but see the flag still 0
.
So, my question is: Do the pthread_cond_broadcast
and pthread_cond_signal
calls imply a write memory barrier? If so, where is this specified in the relevant POSIX (or other) specifications? The spec seemed unclear on this point.
Note: I am aware that, in practice, this does result in a memory barrier (on Linux, because thread awakening implies a full CPU memory barrier, and the cross-library function call implies a compiler memory barrier). However, I'm interested here in what the spec guarentees.
Regardless of whether it implies a memory barrier, the code is still not correct. Consider the read side:
while (flag == 0)
pthread_cond_wait(&cvar, &mutex);
If the read side is suspended between testing flag == 0
and executing the wait, the write side can execute the flag = 1; pthread_cond_signal(&cvar);
. The read side will then miss the wakeup entirely - it will wait forever. Remember that wakeups are not queued - if there's no waiter when the condition variable is signalled, the signal has no effect. To avoid this, the write side needs to lock the mutex anyway.
Under POSIX, if you write to a variable from one thread and read it from another then you must protect it with a mutex. There is no exception made for pthread_cond_broadcast
.
If your platform/compiler offer atomic variables then they may make additional guarantees about those. For example, if flag
is a C++11 std::atomic<int>
then this code is OK.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With