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

Day*_*ppy 4 c# multithreading threadpool thread-priority

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

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

谢谢

更新 1:我应该更具体,我指的是 Parallel.ForEach 内的线程

Adr*_*tti 5

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

这并不准确。您可以更改线程池的线程优先级(在委托本身内部),它将以新的优先级运行,但当其任务完成时将恢复默认优先级,并将其发送回池。

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

    // Code in this function will run with Highest priority
});
Run Code Online (Sandbox Code Playgroud)

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

是的,它不仅仅适用于线程池的线程。在 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
Run Code Online (Sandbox Code Playgroud)

但:

REALTIME_PRIORITY_CLASS + THREAD_PRIORITY_IDLE == 16
REALTIME_PRIORITY_CLASS + THREAD_PRIORITY_TIME_CRITICAL == 31
Run Code Online (Sandbox Code Playgroud)

此外,线程可以有一个临时的提升(由 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
});
Run Code Online (Sandbox Code Playgroud)

编辑:.NET 任务使用线程池,而不是上面写的仍然适用。例如,如果您要枚举一个集合Parallel.ForEach以提高线程优先级,则必须在循环内执行此操作:

Parallel.ForEach(items, item => {
    Thread.CurrentThread.Priority = ThreadPriority.Highest;

    // Your code here...
});
Run Code Online (Sandbox Code Playgroud)

只是警告:改变优先级时要小心。例如,如果两个线程使用共享资源(受锁保护),则存在许多争用来获取该资源,并且其中一个具有最高优先级,那么您可能会得到非常高的 CPU 使用率(因为 的旋转行为Monitor.Enter) 。这只是一个问题,更多细节请参考MSDN(提高线程优先级甚至可能导致性能更差)。