我正在阅读std::condition_variable
,更具体地说是如何使用std::condition_variable::notify_one
通知等待线程。
我遇到了几个问题,我很乐意得到答案:
notify_one
(操作系统)时会发生什么?我想这是特定于操作系统的,所以为了争论 - 我在Windows工作。notify_one
会发生什么?此调用是否会对性能产生任何影响(CPU周期,电源等)?由于
答案 0 :(得分:3)
在Windows上,std::condition_variable
很可能是根据本机Windows条件变量实现的。
请参阅:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682052(v=vs.85).aspx
在类似unix的系统上,它们通常是根据pthreads信号量/互斥量对实现的。
整个操作应该在用户空间中进行,因此您不需要付费切换到内核模式,但是您将使用两个同步原语。这将意味着将发布内存栅栏,因此总是要付出代价。
简而言之,在你应该的时候调用notify_one
,即在改变状态并释放锁之后,这是一个相当便宜的操作。 1}}在没有充分理由的情况下紧紧调用notify_one
可能不是一个好主意。
如果线程在没有等待线程时调用notify_one会发生什么?
取一个互斥锁,检查线程是否在等待,释放互斥锁。端。
此调用是否会对性能产生任何影响(CPU周期,电源等)?
是的,当然,它消耗了几个周期并且需要CPU正在运行。偶尔做一次也不会有害。在紧密循环中持续进行将耗电。
我想我的问题是,“用例是什么”?如果您每秒向生产者/消费者队列添加一百万个项目,那么您将花费大量时间和精力来通知不存在的消费者。如果你每秒增加10,那么在notify_one
中花费的时间可能甚至不会显示在任何性能跟踪上。
答案 1 :(得分:1)
这些问题非常针对具体实施。只是说你在Windows上是不够的;每个标准库可能有不同的实现,调试版本的实现可能与发布版本不同。
没有线程在等待时notify_one的语义效果是无操作。在实现方面,线程至少必须检查原子变量以确定是否有任何线程在等待。所以有一点开销。
Microsoft标准库的condition_variable是根据并发运行时的条件变量实现的,从Windows Vista开始,该变量是根据WinAPI RTL_CONDITION_VARIABLE实现的。无法实现这一点。但是,它的实现基于这篇微软研究论文是合理的:
http://research.microsoft.com/pubs/64242/implementingcvs.pdf