如果您没有在更改条件和信号的代码路径中锁定互斥锁,则可能会丢失唤醒。考虑以下两个过程:
流程A:
pthread_mutex_lock(&mutex);
while (condition == FALSE)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
过程B(错误):
condition = TRUE;
pthread_cond_signal(&cond);
然后考虑这种可能的指令交错,其中 condition
开始于 FALSE
:
Process A Process B
pthread_mutex_lock(&mutex);
while (condition == FALSE)
condition = TRUE;
pthread_cond_signal(&cond);
pthread_cond_wait(&cond, &mutex);
现在 condition
在 TRUE
等待条件变量 - 它错过了唤醒信号。如果我们改变进程 B 以锁定互斥锁:
过程B(正确):
pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
...那么上述情况就不会发生;唤醒将永远不会被错过。
(请注意,您 实际上 可以 pthread_cond_signal()
本身移动到之后 pthread_mutex_unlock()
,但这可能会导致线程调度不太优化,并且由于更改条件本身,您必然已经在此代码路径中锁定了互斥锁)。