gpt4 book ai didi

.net - SwitchToThread/Thread.Yield 与 Thread.Sleep(0) 与 Thread.Sleep(1)

转载 作者:行者123 更新时间:2023-12-02 03:35:41 25 4
gpt4 key购买 nike

我正在尝试编写最终的“Yield”方法来将当前时间片交给其他线程。到目前为止,我发现有几种不同的方法可以使线程产生其分配的时间片。我只是想确保我正确地解释了它们,因为文档不是很清楚。因此,根据我在 stackoverflow、MSDN 和各种博客文章上阅读的内容,存在以下选项,它们都有不同的优点/缺点:

SwitchToThread [win32]/Thread.Yield [.NET 4 Beta 1]:屈服于任何同一处理器上的线程

  • 优点:大约快两倍Thread.Sleep(0)
  • 缺点:仅产生线程在同一处理器上

Thread.Sleep(0):屈服于任何处理器上具有相同或更高优先级的任何线程

  • 优点:比Thread.Sleep(1)
  • 缺点:仅产生线程具有相同或更高优先级

Thread.Sleep(1):屈服于任何处理器上的任何线程

  • 优点:屈服于任何线程任何处理器
  • 缺点:最慢的选择(Thread.Sleep(1) 通常会如果出现以下情况,则将线程挂起大约 15 毫秒timeBeginPeriod/timeEndPeriod[win32] 未使用)

Thread.SpinWait怎么样?它可以用于产生线程的时间片吗?如果不是的话,它有什么用?

我还有一些遗漏或错误解释的内容。如果您能纠正/补充我的理解,我将不胜感激。

到目前为止,这是我的 Yield 方法的样子:

public static class Thread
{
[DllImport("kernel32.dll")]
static extern bool SwitchToThread();

[DllImport("winmm.dll")]
internal static extern uint timeBeginPeriod(uint period);

[DllImport("winmm.dll")]
internal static extern uint timeEndPeriod(uint period);

/// <summary> yields time slice of current thread to specified target threads </summary>
public static void YieldTo(ThreadYieldTarget threadYieldTarget)
{
switch (threadYieldTarget) {
case ThreadYieldTarget.None:
break;
case ThreadYieldTarget.AnyThreadOnAnyProcessor:
timeBeginPeriod(1); //reduce sleep to actually 1ms instead of system time slice with is around 15ms
System.Threading.Thread.Sleep(1);
timeEndPeriod(1); //undo
break;
case ThreadYieldTarget.SameOrHigherPriorityThreadOnAnyProcessor:
System.Threading.Thread.Sleep(0);
break;
case ThreadYieldTarget.AnyThreadOnSameProcessor:
SwitchToThread();
break;
default: throw new ArgumentOutOfRangeException("threadYieldTarget");
}
}
}

public enum ThreadYieldTarget
{
/// <summary> Operation system will decide when to interrupt the thread </summary>
None,
/// <summary> Yield time slice to any other thread on any processor </summary>
AnyThreadOnAnyProcessor,
/// <summary> Yield time slice to other thread of same or higher piority on any processor </summary>
SameOrHigherPriorityThreadOnAnyProcessor,
/// <summary> Yield time slice to any other thread on same processor </summary>
AnyThreadOnSameProcessor
}

最佳答案

SpinWait 在超线程处理器上很有用。通过超线程,多个操作系统调度的线程可以在同一物理处理器上运行,共享处理器资源。 SpinWait 向处理器表明您没有做任何有用的工作,它应该运行来自不同逻辑 CPU 的代码。顾名思义,它通常在旋转时使用。

假设您有如下代码:

while (!foo) {} // Spin until foo is set.

如果该线程在超线程处理器上的线程上运行,则它会消耗可用于该处理器上运行的其他线程的处理器资源。

更改为:

while (!foo) {Thread.SpinWait(1);} 

我们正在指示 CPU 向其他线程提供一些资源。

SpinWait 不影响操作系统的线程调度。

对于您关于“最终产量”的主要问题,这在很大程度上取决于您的情况 - 如果不澄清为什么您希望线程屈服,您将无法获得好的答案。从我的角度来看,让出处理器的最佳方法是让线程进入等待状态,并且仅在有工作要做时才唤醒。其他任何事情都只是浪费 CPU 时间。

关于.net - SwitchToThread/Thread.Yield 与 Thread.Sleep(0) 与 Thread.Sleep(1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1413630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com