首页 > 解决方案 > 条件变量可以“错过”通知调用吗?

问题描述

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

给定一个互斥量 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 只对其中一个通知调用起作用。

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

这是可能发生的情况吗?我们必须意识到这一点吗?例如,在 A 内,pop UNTIL 队列为空?或者这是由语言处理的?

标签: c++multithreadingc++11

解决方案


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

这是可能发生的情况吗?我们必须意识到这一点吗?例如,在 A 内,pop UNTIL 队列为空?或者这是由语言处理的?

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


推荐阅读