在不锁定互斥锁的情况下调用 pthread_cond_information

我在某个地方读到过,我们应该在调用 Pthread _ cond _ information之前锁定 互斥锁,然后在调用后解锁互斥锁:

Pthread _ cond _ information ()例程是 用来发出信号(或唤醒)另一个 正在等待 条件变量,应该是 在锁定互斥对象之后调用,并且必须 为... 解锁互斥对象 Pthread _ cond _ wait ()例程 完整。

我的问题是: 在不锁定互斥对象的情况下调用 Pthread _ cond _ informationPthread _ cond _ Broadcasting方法是否可行?

56355 次浏览

According to this manual :

The pthread_cond_broadcast() or pthread_cond_signal() functions may be called by a thread whether or not it currently owns the mutex that threads calling pthread_cond_wait() or pthread_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 calling pthread_cond_broadcast() or pthread_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.

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).

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?