.net 线程优先级没有影响?
我创建了一个简单的.NET控制台应用程序,并在其中启动了3个托管线程。每个线程执行以下循环:.net 线程优先级没有影响?,.net,multithreading,.net,Multithreading,我创建了一个简单的.NET控制台应用程序,并在其中启动了3个托管线程。每个线程执行以下循环: while (true) { System.Console.WriteLine(thread.Name + " " + DateTime.Now); Thread.Sleep(10); } 我将第一个线程的优先级设置为高,并让应用程序运行几分钟。总的来说,我希望第一个线程能够更频繁地写入控制台。事实上,它没
while (true)
{
System.Console.WriteLine(thread.Name + " " + DateTime.Now);
Thread.Sleep(10);
}
我将第一个线程的优先级设置为高,并让应用程序运行几分钟。总的来说,我希望第一个线程能够更频繁地写入控制台。事实上,它没有明显的效果。将一个线程的优先级设置为高似乎与将所有三个线程都设置为正常相同
我在这里遗漏了哪些线程优先级可以解释这一点?请尝试Sleep(1)
。10ms是线程时间的永恒,然而Sleep(1)
基本上说“我把剩余的时间片让给另一个线程执行”,我想这就是你想要的。线程优先级不仅仅使线程执行得更频繁,它只是说“如果调度程序在给线程a一个时间片和给线程B一个时间片之间有选择,那么就给优先级更高的线程一个时间片。”尝试这个更改,看看会发生什么。或者,让每个线程花不同的时间执行(但不要为此使用睡眠,在一个循环中打印100个元素,在另一个循环中打印1000个元素,等等)
编辑:更改为睡眠(1),不确定修改的原因。请参阅下面我的评论,了解为什么睡眠(1)是一个更好的选择。尝试Sleep(1)
。10ms是线程时间的永恒,然而Sleep(1)
基本上说“我把剩余的时间片让给另一个线程执行”,我想这就是你想要的。线程优先级不仅仅使线程执行得更频繁,它只是说“如果调度程序在给线程a一个时间片和给线程B一个时间片之间有选择,那么就给优先级更高的线程一个时间片。”尝试这个更改,看看会发生什么。或者,让每个线程花不同的时间执行(但不要为此使用睡眠,在一个循环中打印100个元素,在另一个循环中打印1000个元素,等等)
编辑:更改为睡眠(1),不确定修改的原因。请参阅下面我的评论,了解为什么在这里睡眠(1)是一个更好的选择。线程不会更频繁地向控制台写入,因为它们都在写入之间等待10毫秒。但是,高优先级线程应该更定期地向控制台写入,也就是说,写入间隔应接近真正的10ms。这是因为,虽然较低优先级的线程可能会被PC上的其他任务推到一边,但较高优先级的线程在被允许写入之前需要等待的时间更少
这是否回答了您的问题?线程不会更频繁地向控制台写入,因为它们在写入之间都等待10毫秒。但是,高优先级线程应该更定期地向控制台写入,也就是说,写入间隔应接近真正的10ms。这是因为,虽然较低优先级的线程可能会被PC上的其他任务推到一边,但较高优先级的线程在被允许写入之前需要等待的时间更少
这是否回答了您的问题?如果您丢失了
线程。Sleep
语句您可能会从优先级较高的线程中看到更多操作Thread.Sleep
给其他线程足够的时间做他们的事情。如果丢失线程.Sleep
语句,您可能会看到优先级较高的线程执行更多操作<代码>线程。睡眠为其他线程提供足够的时间来完成它们的工作。如果三个线程的打印时间都少于10毫秒,则不会对输出产生任何影响。试着想出一个需要很长时间的任务,比如说计算100万的平方根,然后看看谁运行得更频繁。如果所有三个线程的打印时间都少于10毫秒,那么您将看不到对输出的任何影响。试着想出一个需要很长时间的任务,比如说计算100万的平方根,然后看看谁运行得更频繁。ThreadPriority可能不会按预期的方式运行。。。一些关于线程优先级的阅读材料
线程优先级是邪恶的线程优先级。低于正常值
为什么睡眠(1)比睡眠(0)好
ThreadPriority可能无法按预期运行。。。一些关于线程优先级的阅读材料 线程优先级是邪恶的
线程优先级。低于正常值
为什么睡眠(1)比睡眠(0)好
您看不到任何区别,因为您可能在多处理器机器上运行此程序,在多处理器机器上,线程不必相互竞争就可以调度在单个内核上 当高优先级线程正在执行时,调度程序仍然可以将低优先级线程调度到其他内核,因此您看不到任何显著差异 如果您想注意到一个显著的差异,就必须强制线程与单个内核竞争一个时间片,在这个内核中一次只能执行一个线程。要实现这一点,您应该将所有线程的处理器关联设置为同一个单核 我不确定在.NET中如何实现这一点,但在C中,您应该使用以下函数:
HANDLE hThreadLow = CreateThread(NULL, 0, ThreadProc1,
NULL, CREATE_SUSPENDED, &dwThreadLowId);
HANDLE hThreadHigh = CreateThread(NULL, 0, ThreadProc2,
NULL, CREATE_SUSPENDED, &dwThreadHighId);
SetThreadPriority(hThreadLow, THREAD_PRIORITY_BELOW_NORMAL);
SetThreadPriority(hThreadHigh, THREAD_PRIORITY_ABOVE_NORMAL);
SetThreadAffinityMask(hThreadHigh, 0x00000001);
SetThreadAffinityMask(hThreadLow, 0x00000001);
ResumeThread(hThreadLow);
ResumeThread(hThreadHigh);
现在您将注意到这两个线程之间的一个显著差异。在两个线程中的每一个线程中实现一个计数器,并查看计数值的差异在100x到10000x之间。您看不到任何差异,因为您可能在多处理器机器上运行此程序,在多处理器机器上,线程不必相互竞争就可以在单个内核上调度 当高优先级线程正在执行时,调度程序仍然可以将低优先级线程调度到其他内核,因此您看不到任何显著差异 如果您想注意到一个显著的差异,就必须强制线程与单个内核竞争一个时间片,在这个内核中一次只能执行一个线程。要实现这一点,您应该将所有线程的处理器关联设置为同一个单核 我不确定
process.ProcessorAffinity = (IntPtr) 0x0001;
// 0x0001 = 0000 0001 - run on 1st core
// 0x0002 = 0000 0010 - run on 2nd core
// 0x0003 = 0000 0011 - run on 1st and 2nd core
// 0x0004 = 0000 0100 - run on 3rd core
// and so on
using System;
using System.Diagnostics;
using System.Threading;
namespace Test
{
class Program
{
private static int highCount, lowCount;
private static readonly ManualResetEventSlim Signal = new ManualResetEventSlim(false);
public static void Main()
{
using (var process = Process.GetCurrentProcess())
{
process.PriorityClass = ProcessPriorityClass.High;
// only run on core number 1
process.ProcessorAffinity = (IntPtr) 0x0001;
}
var slowThread = new Thread(() =>
{
while (true)
{
if (Signal.IsSet)
{
break;
}
Console.WriteLine("Lowest");
lowCount++;
}
})
{
Name = "Lowest",
Priority = ThreadPriority.Lowest
};
var fastThread = new Thread(() =>
{
while (true)
{
if (Signal.IsSet)
{
break;
}
Console.WriteLine("Highest");
highCount++;
}
})
{
Name = "Highest",
Priority = ThreadPriority.Highest
};
fastThread.Start();
slowThread.Start();
Console.ReadKey();
Signal.Set();
fastThread.Join();
slowThread.Join();
Console.WriteLine($"highCount:{highCount} & lowCount:{lowCount}");
Console.ReadKey();
}
}
}