【问题标题】:Difference between Thread.Sleep(0) and Thread.Yield()Thread.Sleep(0) 和 Thread.Yield() 的区别
【发布时间】:2011-02-26 18:28:29
【问题描述】:

由于 Java 很久以前就有 Sleep and Yield,我发现 answers 适用于该平台,但不适用于 .Net

.Net 4 包含新的 Thread.Yield() 静态方法。以前将 CPU 交给其他进程的常用方法是 Thread.Sleep(0)。

除了返回布尔值的 Thread.Yield() 之外,还有其他性能、操作系统内部差异吗?

例如,我不确定 Thread.Sleep(0) 在将当前线程更改为等待状态之前是否检查其他线程是否准备好运行......如果不是这样,当没有其他线程准备好时,Thread.Sleep (0) 似乎比 Thread.Yield() 更糟糕。

【问题讨论】:

    标签: .net multithreading


    【解决方案1】:

    根据 MSDN,

    当使用Sleep(0) 在指定的时间内,操作系统不会安排线程执行。

    使用Yield() 产生线程当前时间片的其余部分。操作系统根据调用线程的优先级和可运行的其他线程的状态,为另一个时间片调度调用线程。

    所以这有一个细微的差别。 Thread.sleep 会将 Thread 置于 SLEEP 模式,并建议它在那里停留给定的毫秒数 Thread.yield 会将其置于 WAIT 模式,因此它可能会立即再次运行,或者可能会有更高的进程线程介入。

    【讨论】:

    • 我认为在 CLR 或操作系统级别都没有 SLEEP 状态,只有 WAITING 和 READY 状态。我认为 Yield 可以直接移至 READY,而 Sleep(n>0) 将移至 WAITING,一旦间隔消失,将其移至 READY。我认为 Sleep(0) 可以直接进入 WAITING,而无需经过 SLEEP 状态。
    • @XoseLluis,即使Yield()在功能上等同于Sleep(0),我更喜欢使用Yield(),因为它清楚地表明了程序员的意图。
    • @GerardoLima - 如果您担心 CPU 使用率,它们在功能上并不相同。 Yield() 使用的 CPU 百分比似乎是 Sleep(0) 的 4 倍。
    【解决方案2】:

    Thread.Sleep(0) 立即放弃线程当前的时间片,主动将 CPU 交给其他线程。

    Framework 4.0 的新 Thread.Yield() 方法做同样的事情 - 除了它只让给在相同处理器上运行的线程。

    source

    【讨论】:

      【解决方案3】:

      正如 Eric Lippert 在他的 Coverity blog 帖子“How does locking work in C#?”中解释的那样,同时演示了如何实现锁定——

      .NET 框架为您提供了多种工具,您可以使用这些工具来构建更复杂的等待策略:Thread.SpinWait 将处理器置于一个紧密循环中,允许您等待几纳秒或几微秒,而不会将控制权让给另一个线程。 Thread.Sleep(0) 将控制权交给任何具有相同优先级的就绪线程,如果没有,则继续在当前线程上运行。 Thread.Yield 将控制权交给与当前处理器关联的任何就绪线程。正如我们所见,Thread.Sleep(1) 将控制权让给了操作系统选择的任何就绪线程。通过仔细选择这些调用的组合并在现实条件下进行性能测试,您可以构建一个高性能的实现,当然这就是 CLR 团队实际所做的。

      【讨论】:

      • 在这种情况下,“处理器”到底是什么意思?逻辑核心?物理芯片?在多核单处理器系统上Sleep(0)Yield 有区别吗?
      • 链接已失效,但仍可通过 Internet 档案获得。建议编辑此链接以将其更新为web.archive.org/web/20161208024416/http://blog.coverity.com/…
      猜你喜欢
      • 2011-06-17
      • 1970-01-01
      • 2010-11-27
      • 2012-07-13
      • 1970-01-01
      • 1970-01-01
      • 2017-02-28
      • 2016-08-01
      • 1970-01-01
      相关资源
      最近更新 更多