调用pthread_cond_signal而不锁定互斥锁

我读到某个地方,我们应该在调用pthread_cond_signal之前锁定互斥锁,并在调用它之后解锁mutext:


pthread_cond_signal()例程用于发信号(或唤醒)另一个正在等待条件变量的线程。它应该在互斥锁锁定后调用,并且必须解锁互斥锁才能完成pthread_cond_wait()例程。


我的问题是:在不锁定互斥锁的情况下调用pthread_cond_signal或pthread_cond_broadcast方法是否可以?


开满天机
浏览 1434回答 3
3回答

慕沐林林

如果不将互斥锁锁定在更改条件和信号的代码路径中,则可能会丢失唤醒。考虑这对过程:流程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 Bpthread_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(),但是这可能导致线程的最佳调度不太理想,并且由于更改了条件本身,您已经锁定了该代码路径中的互斥锁)。

ibeautiful

根据本手册:该pthread_cond_broadcast()或  pthread_cond_signal()功能 可以由一个线程是当前是否拥有互斥体被称为该线程调用pthread_cond_wait() 或pthread_cond_timedwait()已与在他们等待的条件变量相关联; 但是,如果需要可预测的调度行为,则该互斥锁应由线程调用pthread_cond_broadcast()或 锁定  pthread_cond_signal()。可预测的调度行为语句的含义由comp.programming.threads上的Dave Butenhof(使用POSIX线程编程的作者)解释了,并在此处提供。

米琪卡哇伊

caf,在示例代码中,流程B进行了修改,condition而没有先锁定互斥锁。如果进程B在修改过程中只是简单地锁定了互斥锁,然后在调用之前仍然解锁了互斥锁pthread_cond_signal,那将没有问题---我是否正确?我直觉上相信caf的位置是正确的:pthread_cond_signal不拥有互斥锁就打电话是个坏主意。但是,caf的榜样实际上并不是支持这一立场的证据。仅是证明弱点(实际上是不言而喻)的证据,除非您先锁定了该互斥锁,否则修改由互斥锁保护的共享状态是一个坏主意。谁能提供一些示例代码,其中调用pthread_cond_signal后pthread_mutex_unlock产生正确的行为,但调用pthread_mutex_unlock后pthread_cond_signal产生错误的行为?
打开App,查看更多内容
随时随地看视频慕课网APP