问题
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?
回答1:
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:
pthread_mutex_lock(&mutex);
while (condition == FALSE)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
Process B (incorrect):
condition = TRUE;
pthread_cond_signal(&cond);
Then consider this possible interleaving of instructions, where condition
starts out as FALSE
:
Process A Process B
pthread_mutex_lock(&mutex);
while (condition == FALSE)
condition = TRUE;
pthread_cond_signal(&cond);
pthread_cond_wait(&cond, &mutex);
The condition
is now TRUE
, 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):
pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
...then the above cannot occur; the wakeup will never be missed.
(Note that you can actually move the pthread_cond_signal()
itself after the pthread_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).
回答2:
According to this manual :
The
pthread_cond_broadcast()
orpthread_cond_signal()
functions may be called by a thread whether or not it currently owns the mutex that threads callingpthread_cond_wait()
orpthread_cond_timedwait()
have associated with the condition variable during their waits; however, if predictable scheduling behavior is required, then that mutex shall be locked by the thread callingpthread_cond_broadcast()
orpthread_cond_signal()
.
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.
回答3:
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 calling pthread_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 by pthread_mutex_unlock
yields correct behavior, but calling pthread_mutex_unlock
followed by pthread_cond_signal
yields incorrect behavior?
来源:https://stackoverflow.com/questions/4544234/calling-pthread-cond-signal-without-locking-mutex