【发布时间】:2010-11-27 16:05:21
【问题描述】:
我正在尝试编写最终的“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
}
【问题讨论】:
-
您介意我问一下您认为这个库将解决哪类问题吗?
-
if(!Thread.Yield()) { Thread.Sleep(1); }怎么样(感谢 stackoverflow.com/questions/1383943/… )?另请注意,您的代码需要try...finally用于timeBeginPeriod()和timeEndPeriod(),以免在Thread.Sleep()引发异常时中断。
标签: .net multithreading concurrency