WaitOne
公开的AutoResetEvent
方法之类的线程阻塞方法如何不占用资源(CPU等)?
我认为这样的方法只会有一个while循环:
public void WaitOne()
{
while(IsSet == false)
{
// some code to make the thread sleep
}
// finally call delegate
}
但这显然是错误的,因为它会让CPU旋转。那么所有这些黑魔法背后的秘密是什么?
答案 0 :(得分:3)
该方法在内核中实现。对于尚未准备好运行的每个线程,Windows会保留线程正在等待的所有可等待对象(事件等)的列表。当发出可等待的对象信号时,Windows会检查它是否可以唤醒任何等待的线程。不需要投票。
这个channel9讲话有很多关于它是如何工作的信息: http://channel9.msdn.com/shows/Going+Deep/Arun-Kishan-Farewell-to-the-Windows-Kernel-Dispatcher-Lock/
答案 1 :(得分:1)
通常,这些概念依赖于底层操作系统事件构造,一旦触发事件就唤醒挂起的线程(或者如果适用则发生超时)。因此,线程处于挂起状态而不消耗CPU周期。
也就是说,在其他事件类型中还有其他等待变体,其中一些在挂起线程之前尝试旋转几个周期,以防在事件被调用之前或之后被触发。还有一些轻量级锁定原语可以执行等待触发的旋转(如SpinWait
)但必须小心使用它们,因为长时间等待可以驱动CPU。
答案 2 :(得分:1)
AutoResetEvent和ManualResetEvent利用OS功能。有关此主题的更多信息,请参阅CreateEvent。