我读了一些关于std::condition_variable的文章,特别是关于如何使用std::condition_variable::notify_one通知等待线程。
我遇到了几个问题,我很乐意得到答案:
notify_one (操作系统方面的)时,会发生什么?我想这是操作系统特有的,所以为了论证起见,我在Windows中工作。notify_one,会发生什么情况?这个调用有任何性能影响(CPU周期,电源等)吗?谢谢
发布于 2016-02-08 09:00:59
在windows上,std::condition_variable很可能是根据本机Windows条件变量实现的。请参阅:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682052(v=vs.85).aspx
在类似unix的系统上,它们通常是通过线程、信号量/互斥对来实现的。
整个操作应该在用户空间中进行,这样您就不会花钱切换到内核模式,但是您将在幕后处理两个同步原语。这将意味着内存围栏将被发布,所以总有一些代价要付出。
长话短说,应该在更改状态并释放锁之后调用notify_one,这是一个相当便宜的操作。无缘无故地在一个紧循环中调用notify_one可能不是一个好主意。
如果线程在没有等待线程时调用notify_one,会发生什么情况?
采取互斥,检查是否有线程等待,释放互斥。结束。
这个调用有任何性能影响(CPU周期,电源等)吗?
是的,当然,它会消耗几个周期,并且需要CPU运行。偶尔做一次不会有什么害处。在一个紧的循环中连续地这样做会消耗能量。
我想我对你的问题是,“用例是什么”?如果您在生产者/消费者队列中每秒添加一百万项,那么您将花费大量的时间和精力通知不存在的消费者。如果您每秒钟添加10次,那么在notify_one上花费的时间可能甚至不会出现在任何性能跟踪上。
发布于 2016-02-08 09:05:12
这些问题都是非常特定于实现的。仅仅说你在Windows上是不够的;每个标准库可能有不同的实现,而一个调试版本可能有一个与发布版本不同的实现。
当没有线程等待时,notify_one的语义效果是无操作的.在实现方面,线程至少必须检查一个原子变量,以确定是否有线程在等待。所以这里有一些开销。
微软标准库的condition_variable是根据并发运行时的条件变量实现的,从Windows开始,它是根据WinAPI RTL_CONDITION_VARIABLE实现的。这方面的执行是无法实现的。然而,它的实现有一个合理的可能性是基于这篇微软的研究论文:
http://research.microsoft.com/pubs/64242/implementingcvs.pdf
https://stackoverflow.com/questions/35265409
复制相似问题