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

时间:2015-06-25 08:57:42

标签: c# multithreading threadpool thread-priority

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

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

谢谢

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

3 个答案:

答案 0 :(得分:4)

  

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

这不完全正确。您可以更改线程池的线程优先级(在委托内部)并且它将以新的优先级运行,但是当其任务完成并且它将成为默认值时将恢复默认值。送回游泳池。

ThreadPool.QueueUserWorkItem(delegate(object state) {
    Thread.CurrentThread.Priority = ThreadPriority.Highest;

    // Code in this function will run with Highest priority
});
  

是在线程池上运行的特定任务的优先级,它与调用进程优先级有多大关系?

是的,它不仅适用于线程池的线程。在Windows进程中#39;优先级由其类(从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

此外,线程可以有一个临时的 boost (由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使用率结束(因为{{3} } Monitor.Enter)。这只是一个问题,有关详细信息,请参阅MSDN(增加线程的优先级甚至可能导致性能下降)。

答案 1 :(得分:1)

  

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

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

答案 2 :(得分:0)

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

那就是说,你不应该真正改变的所有,线程池的线程优先级。你不是真的需要,并且线程(和处理)优先级不会像你预期的那样工作 - 它只是不值得。保持一切正常,只要忽略Priority属性,你就可以避免许多不必要的问题:)

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