I read somewhere that we should lock the mutex before calling pthread_cond_signal and unlock the mutext after calling it:
The pthread_cond_signal() routine is used to signal (or wake up) another thread which is waiting on the condition variable. It should be called after mutex is locked, and must unlock mutex in order for pthread_cond_wait() routine to complete.
My question is: isn't it OK to call pthread_cond_signal or pthread_cond_broadcast methods without locking the mutex?
According to this manual :
The meaning of the predictable scheduling behavior statement was explained by Dave Butenhof (author of Programming with POSIX Threads) on comp.programming.threads and is available here.
caf, in your sample code, Process B modifies
condition
without locking the mutex first. If Process B simply locked the mutex during that modification, and then still unlocked the mutex before callingpthread_cond_signal
, there would be no problem --- am I right about that?I believe intuitively that caf's position is correct: calling
pthread_cond_signal
without owning the mutex lock is a Bad Idea. But caf's example is not actually evidence in support of this position; it's simply evidence in support of the much weaker (practically self-evident) position that it is a Bad Idea to modify shared state protected by a mutex unless you have locked that mutex first.Can anyone provide some sample code in which calling
pthread_cond_signal
followed bypthread_mutex_unlock
yields correct behavior, but callingpthread_mutex_unlock
followed bypthread_cond_signal
yields incorrect behavior?If you do not lock the mutex in the codepath that changes the condition and signals, you can lose wakeups. Consider this pair of processes:
Process A:
Process B (incorrect):
Then consider this possible interleaving of instructions, where
condition
starts out asFALSE
:The
condition
is nowTRUE
, but Process A is stuck waiting on the condition variable - it missed the wakeup signal. If we alter Process B to lock the mutex:Process B (correct):
...then the above cannot occur; the wakeup will never be missed.
(Note that you can actually move the
pthread_cond_signal()
itself after thepthread_mutex_unlock()
, but this can result in less optimal scheduling of threads, and you've necessarily locked the mutex already in this code path due to changing the condition itself).