为什么 Thread.Sleep(0) 时间片在优先级较低的线程上处理?
Why Thread.Sleep(0) time-slice handled over threads with lower priorities?
据我所知,Thread.Sleep(0) 仅将时间片提供给具有相同或更高优先级的另一个线程。 我做了一些测试应用程序:
class Program
{
public static void ThreadMethod()
{
for (int i = 0; i < 300; i++)
{
Thread.Sleep(0);
Console.WriteLine("{0} ThreadProc: {1}, prio {2} ", Thread.CurrentThread.ManagedThreadId,
i, Thread.CurrentThread.Priority);
}
}
public static void Main()
{
Thread.CurrentThread.Priority = ThreadPriority.Normal;
Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Priority = ThreadPriority.Highest;
Thread t2 = new Thread(new ThreadStart(ThreadMethod));
t2.Priority = ThreadPriority.Lowest;
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)1;
t.Start();
t2.Start();
t2.Join();
t.Join();
}
}
这是模拟单核CPU,据我了解这里应该只执行最高优先级的线程,但是我看到的是:
低优先级线程在每次操作时不断更改高优先级
线程正在相互转换。 (当然开始和结束的情况是不同的,但是最高级的线程应该总是得到更多的时间片)
为什么不是一直这样?
低优先级线程必须执行更少的时间
你有 2 个线程:t
(高优先级)和 t2
(低优先级),还有主线程。当高优先级线程执行 Thread.Sleep(0)
时 - 它可以为其时间片提供的唯一其他线程是 t2
,因为即使它具有较低的优先级 - 也没有其他选择。主线程被 Join()
阻塞并且没有代码到 运行,它不需要时间片。
要查看您期望的行为 - 再添加一个具有高优先级的线程:
public static void Main() {
Thread.CurrentThread.Priority = ThreadPriority.Normal;
Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Priority = ThreadPriority.Highest;
Thread t2 = new Thread(new ThreadStart(ThreadMethod));
t2.Priority = ThreadPriority.Lowest;
Thread t3 = new Thread(new ThreadStart(ThreadMethod));
t3.Priority = ThreadPriority.Highest;
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr) 1;
t.Start();
t2.Start();
t3.Start();
t3.Join();
t2.Join();
t.Join();
}
然后您会看到高优先级线程将它们的时间片分配给彼此,因此它们几乎都将独占执行它们的循环,并且只有在它们完成后 - 低优先级线程才会执行它的循环。