[英]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_signal或pthread_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()
orpthread_cond_signal()
functions may be called by a thread whether or not it currently owns the mutex that threads callingpthread_cond_wait()
orpthread_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 callingpthread_cond_broadcast()
orpthread_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.