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

Any relationship between process priority and thread pool priority (C#)

我知道线程池优先级 should/can 不会被 运行ning 进程改变,但是线程池上特定任务 运行ning 的优先级有点定价与调用进程优先级?

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

谢谢

更新 1:我应该更具体一些,我指的是 Parallel.ForEach

中的线程

do all tasks in thread pool run in the same priority regardless the calling process priority?

他们必须这样做。唯一落在游泳池的是代表。它包含对对象的引用,但不包含将其删除的线程。

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

就是说,您根本不应该真正更改线程优先级,线程池与否。您实际上并不需要,并且线程(和进程)优先级不会按照您可能期望的方式工作——这是不值得的。一切正常,忽略有个Priority 属性,就可以避免很多不必要的问题了:)

您会在互联网上找到很多很好的解释 - 例如,http://blog.codinghorror.com/thread-priorities-are-evil/。当然,这些通常是过时的 - 但线程优先级的概念也是如此,真的 - 它们是为单核机器设计的,当时 OSes 并不是那么擅长抢占式多任务处理,真的.

I understand that thread pool priority should/can not be changed by the running process,

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

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

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

is the priority of particular task running on the thread pool somewhat priced-in with the calling process priority?

是的,它不仅仅适用于线程池的线程。在 Windows 中,进程的优先级由其 class 指定(从 IDLE_PRIORITY_CLASSREALTIME_PRIORITY_CLASS)。连同线程的优先级(从 THREAD_PRIORITY_IDLETHREAD_PRIORITY_TIME_CRITICAL),它将用于计算线程的 final 优先级。

来自 MSDN:

The process priority class and thread priority level are combined to form the base priority of each thread.

请注意,这不仅仅是基本优先级加上偏移量:

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 调度程序决定和管理)。请注意,进程也可以更改自己的优先级 class.

in other words, do all tasks in thread pool run in the same priority regardless the calling process priority?

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

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 behaviorMonitor.Enter)。这只是一个问题,更多细节请参考MSDN(增加线程的优先级甚至可能导致更差的性能)。