【问题标题】:Does using Thread.Sleep use more of the processor than ManualResetEvent would when a thread waits for signal from another thread?当一个线程等待来自另一个线程的信号时,使用 Thread.Sleep 是否比 ManualResetEvent 使用更多的处理器?
【发布时间】:2020-01-22 01:17:25
【问题描述】:

我将 Thread.Sleep 用于较低优先级的线程,以在线程处理之前等待变量递增;然后它循环并再次等待相同的变量。

如果我有很多相同类别的线程,比如 1000 个实例,与使用 ManualResetEvent 而不是 Thread.Sleep 相比,这会花费更多的处理器周期吗?

【问题讨论】:

  • 请分享你的代码
  • 这个问题对我来说似乎没有多大意义。无论线程如何进入此状态,处于等待状态的线程都不会消耗 CPU:通过调用 Sleep 或等待句柄。可能不同的是系统调度程序检查唤醒事件的频率(在Sleep 的情况下,它由指定为参数的周期决定)。所以回答would this take substantially more processor cycles - 它不应该对调度程序(在这种情况下是主要的 CPU 消费者)产生任何影响,因为这仅意味着在两种情况下遍历相同大小的线程队列。
  • 在 Thread.Sleep() 期间调度程序多久唤醒一次线程?

标签: .net multithreading


【解决方案1】:
while (weAreNotReady) 
{ 
    // nothing here, keep looping
}
WeAreReadyToDoSomething();

上面叫Busy waiting。优点:我们会尽快通知您。缺点:100% CPU。

while (weAreNotReady)
{
   Thread.Sleep(someTime);
}
WeAreReadyDoSomething();

上面叫Polling。优点:如果“someTime”足够大,CPU 很少。缺点:如果“someTime”很小,则相当于忙等待。如果“someTime”很长,则会出现不必要的延迟。

ManualResetEvent 或其他一些事件驱动选项显然是最好的,但有时无法实现。

所以回答您的问题:是的,与事件驱动的方法相比,进行轮询需要更多的周期。是不是“实质上”更多?这取决于你的睡眠时间()。

【讨论】:

  • 几秒钟内“someTime”的大小是多少?在我的例子中,Thread.sleep(n) 将是 n 介于 0.1 和 0.1 秒之间。
  • 如果没有上下文,我无法回答这个问题。在某些情况下,每天或每小时轮询一次是可以的。在其他情况下,需要每秒轮询 10000 次。这一切都取决于特定的情况。因此,这样的超时通常不是硬编码的,而是可配置的,因此可以在以后需要时进行修改。
  • 有时稍微忙一点的等待可能比 ManualResetEvent 更快。 docs.microsoft.com/en-us/dotnet/standard/threading/spinwait
【解决方案2】:

通常:使用轮询(有或没有 Thread.Sleep),CPU 时间被浪费了,因为每个线程都在不断唤醒并使用 CPU 来检查变量。对于事件,不会浪费任何 CPU 时间,因为线程在设置事件之前根本不会运行

例外:如果变量经常变化,使得线程每次只需要轮询一次或两次,也就意味着不会浪费多少CPU,那么轮询效率会更高。

【讨论】:

  • 谢谢。我相信这就是答案.....出于好奇,Windows 10 上的线程多久执行一次 Thread.sleep(n) “唤醒”以检查时间?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多