简体   繁体   English

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

[英]Calling pthread_cond_signal without locking mutex

I read somewhere that we should lock the mutex before calling pthread_cond_signal and unlock the mutex after calling it:我在某处读到我们应该在调用pthread_cond_signal之前锁定互斥锁并在调用它之后解锁互斥锁:

The pthread_cond_signal() routine is used to signal (or wake up) another thread which is waiting on the condition variable. pthread_cond_signal() 例程用于通知(或唤醒)另一个正在等待条件变量的线程。 It should be called after mutex is locked, and must unlock mutex in order for pthread_cond_wait() routine to complete.它应该在互斥锁被锁定后调用,并且必须解锁互斥锁才能完成 pthread_cond_wait() 例程。

My question is: isn't it OK to call pthread_cond_signal or pthread_cond_broadcast methods without locking the mutex?我的问题是:在不锁定互斥锁的情况下调用pthread_cond_signalpthread_cond_broadcast方法不是可以吗?

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):流程B(错误):

condition = TRUE;
pthread_cond_signal(&cond);

Then consider this possible interleaving of instructions, where condition starts out as FALSE :然后考虑这种可能的指令交错,其中condition开始为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. condition现在为TRUE ,但进程 A 卡在等待条件变量 - 它错过了唤醒信号。 If we alter Process B to lock the mutex:如果我们改变进程 B 来锁定互斥锁:

Process B (correct):流程B(正确):

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). (请注意,你其实可以移动pthread_cond_signal()本身后pthread_mutex_unlock()但是这可能会导致线程较少优化调度,和你一定已经锁定互斥在这个代码路径,由于不断变化的条件本身)。

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;线程可以调用pthread_cond_broadcast()pthread_cond_signal()函数,无论它当前是否拥有调用pthread_cond_wait()pthread_cond_timedwait()线程在等待期间与条件变量关联的互斥锁 however, if predictable scheduling behavior is required, then that mutex shall be locked by the thread calling pthread_cond_broadcast() or pthread_cond_signal() .但是,如果需要可预测的调度行为,则该互斥锁应由调用pthread_cond_broadcast()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 . Dave Butenhof( Programming with POSIX Threads 的作者)在 comp.programming.threads 上解释了可预测调度行为语句的含义,可在此处获取

caf, in your sample code, Process B modifies condition without locking the mutex first. caf,在您的示例代码中,进程 B 修改condition而不先锁定互斥锁。 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?如果进程 B 在修改过程中简单地锁定了互斥锁,然后在调用pthread_cond_signal之前仍然解锁了互斥锁,那么就没有问题——我是对的吗?

I believe intuitively that caf's position is correct: calling pthread_cond_signal without owning the mutex lock is a Bad Idea.我凭直觉相信 caf 的立场是正确的:在不拥有互斥锁的情况下调用pthread_cond_signal是一个坏主意。 But caf's example is not actually evidence in support of this position;但 caf 的例子实际上并不是支持这一立场的证据; 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?任何人都可以提供一些示例代码,其中调用pthread_cond_signal后跟pthread_mutex_unlock产生正确的行为,但调用pthread_mutex_unlock后跟pthread_cond_signal产生不正确的行为?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 不锁定 pthread_cond_timedwait 和 pthread_cond_signal 的互斥(在 Linux 上) - Not locking mutex for pthread_cond_timedwait and pthread_cond_signal ( on Linux ) pthread_cond_signal函数是否解锁了调用线程锁定的互斥锁? - Does pthread_cond_signal function unlock the mutex the calling thread locked? 条件变量 - 为什么在调用 pthread_cond_wait() 之前调用 pthread_cond_signal() 是一个逻辑错误? - condition variable - why calling pthread_cond_signal() before calling pthread_cond_wait() is a logical error? pthread_mutex_unlock前后的pthread_cond_signal之间的区别 - Difference between pthread_cond_signal before and after pthread_mutex_unlock 为什么挂在pthread_cond_signal中 - why is it hanged in pthread_cond_signal pthread_cond_wait和pthread_cond_signal的性能 - pthread_cond_wait and pthread_cond_signal's performance 理解 pthread_cond_wait() 和 pthread_cond_signal() - understanding of pthread_cond_wait() and pthread_cond_signal() Linux:pthread_cond_signal()在Signal Handler()内部不起作用 - Linux : pthread_cond_signal() is not working inside a Signal Handler() 如果pthread_cond_wait在它之前发出信号时,是否会丢失信号 - if pthread_cond_wait can loss signal when pthread_cond_signal signal before it pthread_cond_wait从pthread_cond_signal丢失信号 - pthread_cond_wait lost signal from pthread_cond_signal
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM