条件变量 - 为什么在调用pthread_cond_wait()之前调用pthread_cond_signal()是一个逻辑错误?

Ash*_*ban 23 c c++ pthreads condition-variable

它是在POSIX线程教程https://computing.llnl.gov/tutorials/pthreads/ 中编写的 ,这是一个逻辑错误.

我的问题是为什么它是一个逻辑错误?

在我的程序中,我需要使用这些信号,但是我不能保证会有一个处于_cond_wait状态的线程.我试图测试它,没有任何反应.这会导致意外行为还是更糟?

谢谢!

ste*_*anv 36

火焰的答案最接近,但并不完全清楚:
条件变量只应用于表示条件的变化.

线程1检查条件.如果条件不满足,他会等待条件变量,直到条件满足为止.因为首先检查条件,所以他不应该关心条件变量是否已发出信号:

pthread_mutex_lock(&mutex); 
while (!condition)
    pthread_cond_wait(&cond, &mutex); 
pthread_mutex_unlock(&mutex);
Run Code Online (Sandbox Code Playgroud)

线程2改变条件并通过条件变量发出变化信号.他不关心线程是否在等待:

pthread_mutex_lock(&mutex); 
changeCondition(); 
pthread_mutex_unlock(&mutex); 
pthread_cond_signal(&cond)
Run Code Online (Sandbox Code Playgroud)

底线是:通过某种条件完成通信.条件变量仅唤醒等待线程,以便它们可以检查条件.

条件示例:

  • 队列不为空,因此可以从队列中获取条目
  • 设置了布尔标志,因此线程等待直到另一个线程发出信号可以继续
  • 设置了位集中的一些位,因此等待线程可以处理相应的事件

另见pthread示例

  • @Duke:不,不应该.我曾经也这么认为,但没有理由为什么它应该,当接收方具有相同或更高的优先级时,你有2个额外的上下文切换,因为接收方必须阻塞,直到发送方解锁互斥锁. (5认同)
  • 在第二个代码中,我认为pthread_cond_signal(&cond)应该在互斥锁之间 (3认同)

ser*_*ico 5

我的2分钱:我不知道在没有线程被阻塞时调用* pthread_cond_wait()*的副作用。这实际上是一个实现细节,我想的是,如果您的线程/ timimg模型不能保证wait和signal之间的严格顺序,那么当您可以发出信号时,可能应该考虑使用不同的同步机制[例如,简单的信号灯 ]。即使线程A尚未到达同步点,也要从线程B发送信号量。当线程A到达同步点时,它将发现信号量已增加并进入关键会话。

  • +1建议信号量,这通常更容易正确使用。 (2认同)

ber*_*oal 5

我写下我的答案是因为我看不到能让人们平静下来的答案。我还在该教程中偶然发现了有关 \xe2\x80\x9c 逻辑错误\xe2\x80\x9d 的奇怪令人不安的警告。请注意,关于 的 POSIX 文档文章pthread_cond_signal中没有关于此 \xe2\x80\x9cerror\xe2\x80\x9d 的内容。我确信这是一个不幸的术语选择,或者是教程作者的一个明显错误。他们的声明可能会被解释为在这种情况下进程将因错误而终止,或者任何允许这种情况的程序都是不正确的。这类事情都不是真的。这种情况很常见。文档说

\n\n
\n

pthread_cond_signal()如果 上当前没有阻塞的线程,则和函数pthread_cond_broadcast()\n 不起作用cond

\n
\n\n

所以不要担心,要开心。

\n