[英]condition variable - why calling pthread_cond_signal() before calling pthread_cond_wait() is a logical error?
It's written in POSIX threads tutorial https://computing.llnl.gov/tutorials/pthreads/ that it is a logical error.它写在 POSIX 线程教程https://computing.llnl.gov/tutorials/pthreads/ 中,这是一个逻辑错误。
my question is why it is a logical error?我的问题是为什么这是一个逻辑错误?
In my program i need to use these signals, however i cannot guarantee that there will be a thread that will be in _cond_wait state.在我的程序中,我需要使用这些信号,但是我不能保证会有一个处于 _cond_wait 状态的线程。 I tried to test it and nothing happens.
我试图测试它,但没有任何反应。 Is this can cause unexpected behavior or worse?
这会导致意外行为或更糟吗?
thank you!谢谢你!
The answer of blaze comes closest, but is not totally clear: blaze 的答案最接近,但并不完全清楚:
conditional variables should only be used to signal a change in a condition .条件变量应该只用于表示条件的变化。
Thread 1 checks a condition.线程 1 检查条件。 If the condition doesn't meet, he waits on the condition variable until the condition meets.
如果条件不满足,他就等待条件变量,直到条件满足。 Because the condition is checked first, he shouldn't care whether the condition variable was signaled:
因为先检查条件,所以他不应该关心条件变量是否发出信号:
pthread_mutex_lock(&mutex);
while (!condition)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
Thread 2 changes the condition and signals the change via the condition variable.线程 2 更改条件并通过条件变量发出更改信号。 He doesn't care whether threads are waiting or not:
他不在乎线程是否在等待:
pthread_mutex_lock(&mutex);
changeCondition();
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond)
The bottom line is: the communication is done via some condition.底线是:通信是通过某种条件完成的。 A condition variable only wakes up waiting threads so they can check the condition .
条件变量只唤醒等待线程,以便它们可以检查条件。
Examples for conditions:条件示例:
see also pthread example另见pthread 示例
My 2 cents: I do not know the side effects of calling *pthread_cond_signal()* when no thread has been blocked calling *pthread_cond_wait()*.我的 2 美分:当没有线程被阻塞调用 *pthread_cond_wait()* 时,我不知道调用 *pthread_cond_signal()* 的副作用。 This is really an implementation detail What I think is that, if your threading/timimg model do not guarantee the rigth order between wait and signal, probably you should consider a different sync mechanism [like a simple semaphore , for example] when you can signal the semaphore from thread B even if the thread A has nor reached the sync point.
这真的是一个实现细节我认为,如果您的线程/timimg 模型不能保证等待和信号之间的正确顺序,那么您可能应该考虑使用不同的同步机制 [例如简单的信号量],当您可以发出信号时来自线程 B 的信号量,即使线程 A 还没有到达同步点。 When thread A will reach the sync point, it will find the semaphore incremented and will enter the critical session.
当线程 A 将到达同步点时,它会发现信号量增加并进入关键会话。
I write my answer because I do not see the one that will calm people.我写我的答案是因为我没有看到能让人们平静的答案。 I also stumbled upon that bizarre disturbing warning about “logical error” in that tutorial.
我还在那个教程中偶然发现了关于“逻辑错误”的奇怪的令人不安的警告。 Note that there is nothing about this “error” in the POSIX documentation article on
pthread_cond_signal
.请注意, 关于
pthread_cond_signal
的 POSIX 文档文章中没有关于此“错误”的任何内容。 I am sure that this is an unfortunate choice of the term or a plain mistake on part of the author of the tutorial.我确信这是一个不幸的术语选择,或者是教程作者的一个明显错误。 Their claim may be interpreted as if a process will terminate with an error in this situation or that any program permitting this situation is incorrect.
他们的声明可能被解释为在这种情况下进程将因错误而终止,或者任何允许这种情况的程序都是不正确的。 Nothing of the sort is true.
没有什么是真的。 Such situations are common.
这种情况很常见。 The documentation says that
文档说
The
pthread_cond_signal()
andpthread_cond_broadcast()
functions have no effect if there are no threads currently blocked oncond
.如果当前没有线程阻塞在
cond
上,则pthread_cond_signal()
和pthread_cond_broadcast()
函数无效。
So don't worry and be happy.所以不要担心,要快乐。
A condition variable allows one thread to wake another up from a wait.条件变量允许一个线程从等待中唤醒另一个线程。 They work only if there is a thread waiting at the moment when you trigger the condition.
只有当您触发条件时有线程在等待时,它们才起作用。 The way to ensure that this is the case is for the waiting thread to lock a mutex which is linked to the condition, and for the signalling thread to lock that mutex before triggering the condition.
确保这种情况的方法是等待线程锁定链接到条件的互斥锁,并且信号线程在触发条件之前锁定该互斥锁。 In other words, the signalling thread can only lock the mutex and trigger the condition if the other thread had the mutex locked but is now waiting.
换句话说,如果另一个线程锁定了互斥锁但现在正在等待,则信号线程只能锁定互斥锁并触发条件。
I'm most familiar with boost, so I'll use that in this example:我最熟悉 boost,所以我将在这个例子中使用它:
// A shared mutex, global in this case.
boost::mutex myMutex;
// Condition variable
boost::condition_variable myCondition;
void threadProc()
{
// Lock the mutex while the thread is running.
boost::mutex::scoped_lock guard( myMutex );
while( true )
{
// Do stuff, then...
myCondition.wait( guard ); // Unlocks the mutex and waits for a notification.
}
}
void func()
{
// Function wants to trigger the other thread. Locks the mutex...
boost::mutex::scoped_lock guard( myMutex );
// Since the mutex is locked, we know that the other thread is
// waiting on the condition variable...
myCondition.notify_all();
}
To signal a condition variable when there is no corresponding wait is a logical error because nothing will ever receive the signal.在没有相应的等待时向条件变量发出信号是一个逻辑错误,因为没有任何东西会收到信号。 Condition variables don't remain in a signalled state.
条件变量不会保持在有信号的状态。
If you do not care that this signal will be lost - there is no error.如果你不关心这个信号会丢失 - 没有错误。 It is only an error if you expect later coming waiting thread to wake from cond_wait() immediately.
如果您希望稍后等待的线程立即从 cond_wait() 唤醒,这只是一个错误。
Since this is usual use case for pthread_cond, tutorial calls this logical error.由于这是 pthread_cond 的常见用例,因此教程称此为逻辑错误。 But nothing will crash and no unexpected behavior will occur.
但是什么都不会崩溃,也不会发生意外行为。 In normal execution flow cond_signal() still may be issued when there is no threads in cond_wait(): fe, all readers may be just doing message processing when writer adds another data piece in queue.
在正常的执行流程中,当cond_wait()中没有线程时,仍然可能会发出cond_signal():fe,当写入器向队列中添加另一个数据时,所有读取器可能只是在进行消息处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.