知识卡片
唤醒不等于条件成立
内容
条件变量可能虚假唤醒,裸通知也不会自动保存发生过的事件。应在同一同步协议下保存状态,并在等待时重新检查谓词;把醒来当作条件已满足,会漏掉等待顺序及虚假唤醒的边界。一次性事件也可考虑[[void future传事件]]。
参考来源
- 位置:《Effective Modern C++》第7章《并发API》,条款三十九:对于一次性事件通信考虑使用 void 的 futures(源文件:_epub-src/EPUB/text/ch008.xhtml)
- 结论依据:原文并列讨论通知早于等待和虚假唤醒两种问题,给出谓词检查方案。
- 原始内容:如果在反应任务 wait 之前检测任务通知了条件变量,反应任务会挂起 。为了能使条件变量唤醒另一个任务,任务必须等待在条件变量上。如果在反应任务 wait 之前检测任务就通知了条件变量,反应任务就会丢失这次通知,永远不被唤醒。 wait 语句虚假唤醒 。线程API的存在一个事实(在许多语言中——不只是C++),等待一个条件变量的代码即使在条件变量没有被通知时,也可能被唤醒,这种唤醒被称为 虚假唤醒 ( spurious wakeups …