等待方法不占用资源

时间:2011-10-26 15:53:36

标签: c# multithreading

WaitOne公开的AutoResetEvent方法之类的线程阻塞方法如何不占用资源(CPU等)?

我认为这样的方法只会有一个while循环:

public void WaitOne()
{
    while(IsSet == false)
    {
        // some code to make the thread sleep    
    }

    // finally call delegate
}

但这显然是错误的,因为它会让CPU旋转。那么所有这些黑魔法背后的秘密是什么?

3 个答案:

答案 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