进程优先级和线程池优先级之间的任何关系(C#)

我知道线程池优先级应该/不能被正在运行的进程更改,但是在线程池上运行的特定任务的优先级是否与调用进程优先级有些相关?

换句话说,无论调用进程优先级如何,线程池中的所有任务都以相同的优先级运行?

谢谢

更新1:我应该更具体,我引用Parallel.ForEach中的线程

我知道正在运行的进程应该/不能更改线程池优先级,

那不是确切的。 您可以更改线程池的线程优先级(在委托内部)并且它将以新的优先级运行,但是当其任务完成时它将被恢复,并且它将被发送回池。

ThreadPool.QueueUserWorkItem(delegate(object state) { Thread.CurrentThread.Priority = ThreadPriority.Highest; // Code in this function will run with Highest priority }); 

在线程池上运行的特定任务的优先级是否与调用进程优先级有些相关?

是的,它不仅适用于Thread Pool的线程。 在Windows进程中,优先级由其类(从IDLE_PRIORITY_CLASSREALTIME_PRIORITY_CLASS )给出。 与线程的优先级(从THREAD_PRIORITY_IDLETHREAD_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 

此外,线程可以临时增强 (由Windows Scheduler决定和管理)。 请注意,进程也可以更改自己的优先级。

换句话说,无论调用进程优先级如何,线程池中的所有任务都以相同的优先级运行?

不,线程的优先级取决于进程的优先级(参见上一段),并且池中的每个线程可以临时具有不同的优先级。 另请注意,线程优先级不受调用方线程优先级的影响:

 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使用率结束(因为Monitor.Enter的旋转行为 ) Monitor.Enter )。 这只是一个问题,请参阅MSDN以获取更多详细信息(增加线程的优先级甚至可能导致性能更差)。

无论调用进程优先级如何,线程池中的所有任务都以相同的优先级运行?

他们必须。 在游泳池唯一下降的是代表。 它包含对象的引用,但不包含将其删除的Thread。

当前运行的具有相同的优先级。 但是那些尚未运行的队列 – 所以在实践中,存在“优先级”。 更令人困惑的是,OS可以提升(和限制)线程优先级,例如当线程池中的两个线程彼此依赖时(例如,一个阻塞另一个线程)。 当然,任何时候线程池上都有阻塞,你就是在浪费资源:D

也就是说,你根本不应该真正改变线程优先级。 你真的不需要,并且线程(和进程)优先级不会像你预期的那样工作 – 这是不值得的。 保持一切正常,只要忽略有一个Priority属性,你就可以避免很多不必要的问题:)

你会在互联网上找到很多很好的解释 – 例如, http://blog.codinghorror.com/thread-priorities-are-evil/ 。 当然,这些通常是过时的 – 但线程优先级的概念确实如此 – 它们是专为单核机器而设计的,当时操作系统并不是那么擅长先发制人的多任务处理。