我正在阅读
condition_variable
的一些示例代码:
在 cppreference 中,
notify_one()
的调用方式如下:
https://en.cppreference.com/w/cpp/thread/condition_variable
{
std::lock_guard lk(m);
ready = true;
std::cout << "main() signals data ready for processing\n";
}
cv.notify_one();
从上面的代码中,很明显,没有需要使用任何
mutex
来调用notify_one()
。
但是在cplusplus.com,代码是这样的: https://cplusplus.com/reference/condition_variable/condition_variable/
std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all();
看起来应该在调用mutex
之前使用
notify_all()
。我很困惑,
mutex
是
notify_*()
功能所必需的吗?
notify_one
或 notify_all
不是强制性的
。来自
std::condition_variable
文档: 打算修改共享变量的线程要做的第三件事是:
在 std::condition_variable 上执行notify_one或notify_all(不需要持有锁用于通知)
(重点是我的).
但是 - 在锁定状态下调用 notify_*
可能会提供一些 性能优势
。来自对我的答案的
通过解锁,你无缘无故地使notify_all变得更加昂贵 调用之前互斥。如果您在按住时调用notify_all 互斥体,大多数现代实现都知道它不能创建任何线程 准备运行(因为他们需要获取互斥体才能向前推进 进度)并可以进行等待变形优化。这是这样的方式 编码后,notify_all和lck的析构函数都可以创建一个线程 准备运行,导致性能下降。