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);
然后考虑这种可能的指令交错,其中 condition 从 FALSE 开始:
Process A Process B
pthread_mutex_lock(&mutex);
while (condition == FALSE)
condition = TRUE;
pthread_cond_signal(&cond);
pthread_cond_wait(&cond, &mutex);
3 回答
如果未在代码路径中锁定互斥锁以更改条件和信号,则可能会丢失唤醒 . 考虑这对过程:
Process A:
Process B (incorrect):
然后考虑这种可能的指令交错,其中
condition
从FALSE
开始:condition
现在是TRUE
,但是进程A等待条件变量 - 它错过了唤醒信号 . 如果我们改变进程B来锁定互斥锁:Process B (correct):
......那么上面就不会发生;唤醒永远不会错过 .
(请注意,您实际上可以在
pthread_mutex_unlock()
之后移动pthread_cond_signal()
本身,但这可能会导致线程的最佳调度,并且由于更改条件本身,您必须已锁定此代码路径中的互斥锁) .根据本手册:
Dave Butenhof(Programming with POSIX Threads的作者)在comp.programming.threads上解释了可预测调度行为语句的含义,并且可用here .
caf,在您的示例代码中,进程B修改
condition
而不先锁定互斥锁 . 如果进程B在修改期间只是锁定了互斥锁,然后在调用pthread_cond_signal
之前仍然解锁了互斥锁,那么就没有问题 - 我是否正确?我直觉地相信caf的位置是正确的:在不拥有互斥锁的情况下调用
pthread_cond_signal
是一个坏主意 . 但是,咖啡馆的例子并不是支持这一立场的证据;它只是支持弱得多(实际上不言自明)立场的证据,即修改受互斥锁保护的共享状态是一个坏主意,除非你先锁定了这个互斥锁 .任何人都可以提供一些示例代码,其中调用
pthread_cond_signal
后跟pthread_mutex_unlock
会产生正确的行为,但调用pthread_mutex_unlock
后跟pthread_cond_signal
会产生不正确的行为吗?