C++ 是否可以使用条件变量;“小姐”;通知电话?

C++ 是否可以使用条件变量;“小姐”;通知电话?,c++,multithreading,c++11,C++,Multithreading,C++11,我想知道条件变量是否可能“错过”通知调用。我的设想如下 给定一个互斥mu和一个Pred p(!queue.empty()) 线程A:在程序的整个生命周期内持续存在。保存一个等待mu和P的条件变量。在获取mu并验证队列是否为空时,它将从队列中弹出一个项目 线程B:一个获取mu的函数,将其推送到队列 螺纹C:与B相同 线程B和C同时生成 在这个场景中,B首先获取mu,推送到队列,丢弃mu并调用notify。在B调用notify和丢弃mu之间,C获取mu,推送到队列,并调用notify。最后,A获取m

我想知道条件变量是否可能“错过”通知调用。我的设想如下

给定一个互斥mu和一个Pred p(!queue.empty())

线程A:在程序的整个生命周期内持续存在。保存一个等待mu和P的条件变量。在获取mu并验证队列是否为空时,它将从队列中弹出一个项目

线程B:一个获取mu的函数,将其推送到队列

螺纹C:与B相同

线程B和C同时生成

在这个场景中,B首先获取mu,推送到队列,丢弃mu并调用notify。在B调用notify和丢弃mu之间,C获取mu,推送到队列,并调用notify。最后,A获取mu,继续从队列中弹出一个项目并对其进行处理。但是,A仅作用于其中一个notify调用

如果您试图一个接一个地处理队列中的项目,这似乎会造成堆积

这是一种可能发生的情况吗?我们必须意识到这一点吗?例如,在队列中,直到队列为空时才弹出?还是由语言来处理

如果您试图逐个处理队列中的项目,则 似乎造成了一堆

这是一种可能发生的情况吗?我们必须意识到这一点吗? 例如,在队列中,直到队列为空时才弹出?还是这个 由语言处理


是的,这是一种可能发生的情况,你应该意识到这一点。在您描述的场景中,等待可能会唤醒一次(队列中有两个项目)、两次(队列中每个项目一次)甚至N次(队列中没有项目的虚假唤醒。这就是为什么您总是在唤醒后检查谓词,然后在重新等待条件之前确保谓词为false。弹出直到队列为空是一个合理的解决方案。

正如您所说,弹出直到队列为空。条件变量不跟踪有多少notify调用s处于挂起状态。A只对其中一个
notify
调用执行操作有什么问题?您认为A下一步会做什么?问题是,如果A对两个notify调用都不执行操作,则我的队列中有未处理的项。唤醒时,会在cv上检查谓词。wait(lock,verify\u pred),以避免出现虚假唤醒问题。但是,此时我仍然需要处理队列中可能有多个项目必须处理的事实。除了在再次等待之前弹出队列直到队列为空之外,您是否看到其他合理的选择?当谓词为true时,cv.wait()将立即返回(即,不阻塞)而不管它是否被通知。因此,如果谓词是(!queue.empty())或类似的东西,并且队列中有两个项目,它将立即返回,直到队列为空(不一定是它收到的通知数!)这样,当wait()返回wait()时,除了弹出队列一次之外,您可能不需要执行任何操作将继续返回,直到队列是空的。什么是你的谓词?抱歉我没有详细地说——我假设你在使用pthOng.Boost或C++线程改变了动态。好,你应该在调用等待之前获取锁,这是使用等待的先决条件。ex并在检查谓词后等待。如果谓词为false,则返回时锁仍处于锁定状态。是的,一旦解锁,它将等待,直到发出信号(或虚假唤醒)然后在返回之前重新获取锁。@nromer在释放锁之前检查队列是否为空并不重要。无论下一个获得锁的消费者线程是什么,都应该发现队列为非空,而不是等待任何事情。只是不要等待已经发生的事情。