【发布时间】:2019-03-31 09:14:09
【问题描述】:
据我了解,Thread.Yield 可以代替WaitOne 和ManualResetEvent 用于线程信号。
虽然我没有遇到解释 WaitOne 在幕后的确切行为的文档,但我假设它将线程置于等待状态并告诉操作系统调度程序检查是否每次都设置了 ManualResetEvent轮到这个线程进入队列了。如果未设置,调度程序不会进行上下文切换并跳到另一个线程。如果设置,调度程序会将线程置于运行状态,以便WaitOne 之后的代码开始执行。
另一方面,无论ManualResetEvent 的状态如何,使用Thread.Yield 都会导致上下文切换,然后进行检查。
我的理解正确吗?有没有解释WaitOne内部工作原理的文档?
P.S:以下是两个版本的示例代码,用于演示目的:
var signal = new ManualResetEvent(false);
new Thread(() =>
{
Console.WriteLine("Waiting for signal...");
signal.WaitOne();
signal.Dispose();
Console.WriteLine("Got signal!");
}).Start();
Thread.Sleep(2000);
signal.Set(); // "Open" the signal
bool signal = false;
new Thread(() =>
{
Debug.WriteLine("Waiting for signal...");
while(signal == false)
{
Thread.Yield();
}
Debug.WriteLine("Got signal!");
}).Start();
Thread.Sleep(2000);
signal = true; ; // "Open" the signal
【问题讨论】:
-
referencesource.microsoft.com 很棒。 WaitOne
-
WaitOne 是一个半量,它允许一个线程等待另一个线程完成。 msdn 上的示例比您发布的代码更好地了解它的实际工作原理。 msdn.microsoft.com/en-us/library/aa332439(v=vs.71).aspx
-
他们没有任何关系。 Yield() 与信令或同步无关,也不保证线程上下文切换。它也不能将
bool变成同步原语。您将使用它来实现您自己的 SpinWait()。好吧,不要那样做,它已经完成了。 -
@HansPassant MS 文档说:“导致调用线程让步给另一个准备好在当前处理器上运行的线程。”对于 Thread.Yield
-
好吧,猜猜当没有其他线程准备好运行时会发生什么。正常情况。
标签: c# windows multithreading clr