Multithreading boost线程中的假解除阻塞

Multithreading boost线程中的假解除阻塞,multithreading,boost,wait,conditional-statements,Multithreading,Boost,Wait,Conditional Statements,我在《今日》杂志上看到了这个有趣的段落: void wait(boost::unique_lock&lock) 效果:自动调用lock.unlock() 并阻止当前线程。这个 线程将在收到通知时解除阻止 调用此->通知一个()或 此->通知所有(),或虚假地。 当线程被解锁时(对于 不管是什么原因),锁坏了 通过调用lock.lock()重新获取 在等待调用返回之前。这个 也可以通过调用 lock.lock()如果函数以 例外 所以我感兴趣的是“虚假”这个词的含义。为什么线程会因为虚假的原因

我在《今日》杂志上看到了这个有趣的段落:

void wait(boost::unique_lock&lock)

效果:自动调用lock.unlock() 并阻止当前线程。这个 线程将在收到通知时解除阻止 调用此->通知一个()或 此->通知所有(),或虚假地。 当线程被解锁时(对于 不管是什么原因),锁坏了 通过调用lock.lock()重新获取 在等待调用返回之前。这个 也可以通过调用 lock.lock()如果函数以 例外

所以我感兴趣的是“虚假”这个词的含义。为什么线程会因为虚假的原因而被解锁?如何解决这个问题?

给出了Linux的一个原因,即当信号传递到进程时,
futex
系统调用返回。不幸的是,它没有解释其他任何事情(事实上,它要求提供更多信息)

(顺便说一句,这似乎是一个posix范围的概念,不限于boost)可能也会引起您的兴趣。

特别详细

无法预测虚假尾迹: 它们基本上是随机的 用户的观点。但是, 通常发生在线程库 无法可靠地确保等待 线程不会错过通知。 因为错过的通知 使条件变量无效, 线程库将唤醒该线程 从它的等待中,而不是从 风险

他还指出,不应该使用持续时间长的
timed\u wait
重载,通常应该使用带谓词的版本

这是初学者的错误,还有一个 这很容易用简单的方法克服 规则:始终在 等待时循环一个条件 变量更阴险的虫子来了 从计时的等待()

这也很有趣

但是为什么我们需要while循环, 我们不能写:

我们不能。而致命的原因是“等待”可以 返回时不需要任何“通知”电话。 这就是所谓的虚假唤醒 POSIX明确允许。 本质上,只从“等待”返回 指示共享数据可能会丢失 已更改,因此必须删除数据 再次评估

好吧,那为什么这个问题还没有解决呢? 第一个原因是没有人想要 去修理它。正在将呼叫包装为“等待” 对于多个应用程序,非常需要一个循环 其他原因。但这些原因 需要解释,而虚假的 唤醒是一个可以应用的锤子 给任何一个一年级的学生 失败


看起来我们找到了相同的页面,这并不完全出乎意料:)是的,这是我今天研究的一个总结,当时我发现了我所遭受的可怕错误的原因。boost文档在这一点上可能更清晰,我发现boost提升了整个系统的等待和通知功能,特别是在boost::interprocess中,这非常令人沮丧。我只会在你需要跨平台并且现在就完成的情况下使用它。嗯,是的,这并不是一个令人满意的答案,因为它只适用于一个平台,尽管我想如果要让它在Linux上“正确”工作真的非常困难,那么这可能是记录虚假唤醒的一个有效理由
void wait(boost::unique_lock<boost::mutex>& lock)
if (!something_happened)
  c.wait(m);