3 回答
TA贡献2016条经验 获得超9个赞
如果不将互斥锁锁定在更改条件和信号的代码路径中,则可能会丢失唤醒。考虑这对过程:
流程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,但是进程A滞留在条件变量上等待-它错过了唤醒信号。如果我们更改进程B来锁定互斥锁:
进程B(正确):
pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
...那么上述情况就不会发生;唤醒将永远不会被错过。
(请注意,您实际上可以将pthread_cond_signal()自身移动到之后pthread_mutex_unlock(),但是这可能导致线程的最佳调度不太理想,并且由于更改了条件本身,您已经锁定了该代码路径中的互斥锁)。
TA贡献1993条经验 获得超5个赞
根据本手册:
该pthread_cond_broadcast()或 pthread_cond_signal()功能 可以由一个线程是当前是否拥有互斥体被称为该线程调用pthread_cond_wait() 或pthread_cond_timedwait()已与在他们等待的条件变量相关联; 但是,如果需要可预测的调度行为,则该互斥锁应由线程调用pthread_cond_broadcast()或 锁定 pthread_cond_signal()。
可预测的调度行为语句的含义由comp.programming.threads上的Dave Butenhof(使用POSIX线程编程的作者)解释了,并在此处提供。
TA贡献1998条经验 获得超6个赞
caf,在示例代码中,流程B进行了修改,condition而没有先锁定互斥锁。如果进程B在修改过程中只是简单地锁定了互斥锁,然后在调用之前仍然解锁了互斥锁pthread_cond_signal,那将没有问题---我是否正确?
我直觉上相信caf的位置是正确的:pthread_cond_signal不拥有互斥锁就打电话是个坏主意。但是,caf的榜样实际上并不是支持这一立场的证据。仅是证明弱点(实际上是不言而喻)的证据,除非您先锁定了该互斥锁,否则修改由互斥锁保护的共享状态是一个坏主意。
谁能提供一些示例代码,其中调用pthread_cond_signal后pthread_mutex_unlock产生正确的行为,但调用pthread_mutex_unlock后pthread_cond_signal产生错误的行为?
- 3 回答
- 0 关注
- 1433 浏览
添加回答
举报