我理解线程池优先级应该/不能被正在运行的进程更改,但是在线程池上运行的特定任务的优先级是否与调用进程优先级有一定的定价?
换句话说,线程池中的所有任务是否都以相同的优先级运行,而不管调用进程的优先级如何?
谢谢
更新1:我应该更具体一些,我指的是Parallel.ForEach内部的线程
发布于 2015-06-25 01:05:28
我知道线程池优先级应该/不能被正在运行的进程更改,
这可不太准确。您可以更改线程池的线程优先级(内部委托本身),它将以新的优先级运行,但默认优先级将在任务完成后恢复,然后将其发送回池。
ThreadPool.QueueUserWorkItem(delegate(object state) {
Thread.CurrentThread.Priority = ThreadPriority.Highest;
// Code in this function will run with Highest priority
});
在线程池上运行的特定任务的优先级是否与调用进程优先级相关联?
是的,而且它并不只适用于线程池的线程。在Windows中,优先级由其类(从IDLE_PRIORITY_CLASS
到REALTIME_PRIORITY_CLASS
)提供。连同线程的优先级(从THREAD_PRIORITY_IDLE
到THREAD_PRIORITY_TIME_CRITICAL
),它将用于计算线程的最终优先级。
来自MSDN:
将进程优先级类和线程优先级级别组合起来,形成每个线程的基本优先级。
请注意,它不仅仅是一个基本优先级加上一个偏移:
NORMAL_PRIORITY_CLASS + THREAD_PRIORITY_IDLE == 1
NORMAL_PRIORITY_CLASS + THREAD_PRIORITY_TIME_CRITICAL == 15
但是:
REALTIME_PRIORITY_CLASS + THREAD_PRIORITY_IDLE == 16
REALTIME_PRIORITY_CLASS + THREAD_PRIORITY_TIME_CRITICAL == 31
此外,线程可以有一个临时的提升(由决定和管理)。请注意,进程也可以更改自己的优先级类。
换句话说,线程池中的所有任务是否都以相同的优先级运行,而不管调用进程的优先级如何?
不,线程的优先级取决于进程的优先级(见上一段),池中的每个线程可以临时拥有不同的优先级。还请注意,线程优先级不受调用线程优先级的影响:
ThreadPool.QueueUserWorkItem(delegate(object s1) {
Thread.CurrentThread.Priority = ThreadPriority.Highest;
ThreadPool.QueueUserWorkItem(delegate(object s2) {
// This code is executed with ThreadPriority.Normal
Thread.CurrentThread.Priority = ThreadPriority.Lowest;
// This code is executed with ThreadPriority.Lowest
});
// This code is executed with ThreadPriority.Highest
});
编辑:.NET任务使用线程池,而上面写的仍然适用。例如,如果要使用Parallel.ForEach
枚举一个排序规则以增加线程优先级,则必须在循环中这样做:
Parallel.ForEach(items, item => {
Thread.CurrentThread.Priority = ThreadPriority.Highest;
// Your code here...
});
只是一个警告:当你改变优先级时要小心。例如,如果两个线程使用一个共享资源(由一个锁保护),那么会有许多竞争来获取该资源,其中一个具有最高优先级,那么您可能会以非常高的CPU使用率结束(因为spinning behavior of Monitor.Enter
)。这只是一个问题,请参考MSDN了解更多细节(增加线程的优先级可能会导致性能下降)。
发布于 2015-06-25 01:01:31
线程池中的所有任务是否都以相同的优先级运行,而不管调用进程的优先级如何?
他们必须这样做。唯一在泳池里落下来的是一位代表。它保存对对象的引用,但不包含对放置对象的线程的引用。
发布于 2015-06-25 01:04:28
目前正在运行的程序具有相同的优先级。但是那些还没有运行的人排着队--所以在实践中,有一个“优先级”。更令人困惑的是,操作系统可以提高(并限制)线程优先级,例如,当线程池中的两个线程相互依赖时(例如,一个线程阻塞另一个线程)。当然,每当线程池被阻塞时,您就在浪费资源:D
也就是说,您根本不应该改变线程优先级,线程池或不更改线程优先级。你真的不需要这样做,线程(和进程)优先级也不像你所期望的那样工作--这是不值得的。保持一切正常,只需忽略存在Priority
属性,就可以避免许多不必要的问题:)
你会在网上找到很多很好的解释--比如http://blog.codinghorror.com/thread-priorities-are-evil/。当然,这些都是过时的--但线程优先级的概念也是如此,事实上--它们是专为单核计算机设计的,而当时OSes并不擅长先发制人的多任务处理。
https://stackoverflow.com/questions/31045677
复制