简体   繁体   English

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

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

I understand that thread pool priority should/can not be changed by the running process, but is the priority of particular task running on the thread pool somewhat priced-in with the calling process priority? 我理解线程池优先级应该/不能被正在运行的进程更改,但是在线程池上运行的特定任务的优先级是否与调用进程优先级有些相关?

in other words, do all tasks in thread pool run in the same priority regardless the calling process priority? 换句话说,无论调用进程优先级如何,线程池中的所有任务都以相同的优先级运行?

thank you 谢谢

update 1: i should have been more specific, i refer to thread inside Parallel.ForEach 更新1:我应该更具体,我在Parallel.ForEach中引用线程

I understand that thread pool priority should/can not be changed by the running process, 我知道正在运行的进程应该/不能更改线程池优先级,

That's not exact. 那不是确切的。 You can change Thread Pool's thread priority (inside delegate itself) and it'll run with new priority but default one will be restored when its task finishes and it'll be send back to pool. 可以更改线程池的线程优先级(在委托内部)并且它将以新的优先级运行,但是当其任务完成时它将被恢复,并且它将被发送回池。

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? 在线程池上运行的特定任务的优先级是否与调用进程优先级有些相关?

Yes, and it doesn't apply to Thread Pool's threads only. 是的,它不仅适用于Thread Pool的线程。 In Windows process' priority is given by its class (from IDLE_PRIORITY_CLASS to REALTIME_PRIORITY_CLASS ). 在Windows进程中,优先级由其类(从IDLE_PRIORITY_CLASSREALTIME_PRIORITY_CLASS )给出。 Together with thread's priority (from THREAD_PRIORITY_IDLE to THREAD_PRIORITY_TIME_CRITICAL ) it'll be used to calculate thread's final priority. 与线程的优先级(从THREAD_PRIORITY_IDLETHREAD_PRIORITY_TIME_CRITICAL )一起,它将用于计算线程的最终优先级。

From MSDN: 来自MSDN:

The process priority class and thread priority level are combined to form the base priority of each thread. 将进程优先级和线程优先级组合在一起,形成每个线程的基本优先级。

Note that it's not simply a base priority plus an offset: 请注意,它不仅仅是基本优先级加上偏移量:

NORMAL_PRIORITY_CLASS + THREAD_PRIORITY_IDLE  == 1
NORMAL_PRIORITY_CLASS + THREAD_PRIORITY_TIME_CRITICAL == 15

But: 但:

REALTIME_PRIORITY_CLASS + THREAD_PRIORITY_IDLE == 16
REALTIME_PRIORITY_CLASS + THREAD_PRIORITY_TIME_CRITICAL == 31

Moreover threads can have a temporary boost (decided and managed by Windows Scheduler). 此外,线程可以临时增强 (由Windows Scheduler决定和管理)。 Be aware that a process can also change its own priority class. 请注意,进程也可以更改自己的优先级。

in other words, do all tasks in thread pool run in the same priority regardless the calling process priority? 换句话说,无论调用进程优先级如何,线程池中的所有任务都以相同的优先级运行?

No, thread's priority depends on process' priority (see previous paragraph) and each thread in pool can temporary have a different priority. 不,线程的优先级取决于进程的优先级(参见上一段),并且池中的每个线程可以临时具有不同的优先级。 Also note that thread priority isn't affected by caller thread's 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
});

EDIT : .NET tasks uses Thread Pool than what wrote above still applies. 编辑 :.NET任务使用线程池比上面写的仍然适用。 If, for example, you're enumerating a collecition with Parallel.ForEach to increase thread priority you have to do it inside your loop: 例如,如果您使用Parallel.ForEach枚举集合来增加线程优先级,则必须在循环中执行此操作:

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

    // Your code here...
});

Just a warning: be careful when you change priorities. 只是警告:改变优先级时要小心。 If, for example, two threads use a shared resource (protected by a lock), there are many races to acquire that resources and one of them has highest priority then you may end with a very high CPU usage (because of spinning behavior of Monitor.Enter ). 例如,如果两个线程使用共享资源(受锁保护),则有许多种族要获取该资源,其中一个具有最高优先级,那么您可能会以非常高的CPU使用率结束(因为Monitor.Enter旋转行为Monitor.Enter )。 This is just one issue, please refer to MSDN for more details (increasing thread's priority may even result is worse performance). 这只是一个问题,请参阅MSDN以获取更多详细信息(增加线程的优先级甚至可能导致性能更差)。

do all tasks in thread pool run in the same priority regardless the calling process priority? 无论调用进程优先级如何,线程池中的所有任务都以相同的优先级运行?

They have to. 他们必须。 The only thing dropped off at the pool is a delegate. 在游泳池唯一下降的是代表。 That holds a reference to an object but not to the Thread that dropped it off. 它包含对象的引用,但不包含删除它的Thread。

The ones that are currently running have the same priority. 当前正在运行的具有相同的优先级。 But there's a queue for the ones that aren't running yet - so in practice, there is a "priority". 但是那些尚未运行的队列 - 所以在实践中,存在“优先级”。 Even more confusingly, thread priorities can be boosted (and limited) by the OS, for example when two threads in the threadpool depend on each other (eg one is blocking the other). 更令人困惑的是,OS可以提升(和限制)线程优先级,例如当线程池中的两个线程彼此依赖时(例如,一个阻塞另一个)。 And of course, any time something is blocking on the threadpool, you're wasting resources :D 当然,任何时候线程池上都有阻塞,你就是在浪费资源:D

That said, you shouldn't really change thread priorities at all , threadpool or not. 这就是说,你真的不应该改变线程的优先级可言 ,线程池与否。 You don't really need to, and thread (and process) priorities don't work the way you probably expect them to - it's just not worth it. 你真的不需要,并且线程(和进程)优先级不会像你预期的那样工作 - 这是不值得的。 Keep everything at normal, and just ignore that there's a Priority property, and you'll avoid a lot of unnecessary problems :) 保持一切正常,只要忽略Priority属性,你就可以避免很多不必要的问题:)

You'll find a lot of nice explanations on the internet - for example, http://blog.codinghorror.com/thread-priorities-are-evil/ . 你会在互联网上找到很多很好的解释 - 例如, http://blog.codinghorror.com/thread-priorities-are-evil/ Those are usually dated, of course - but so is the concept of thread priorities, really - they were designed for single-core machines at a time when OSes weren't all that good at pre-emptive multitasking, really. 当然,这些通常是过时的 - 但线程优先级的概念确实如此 - 它们是专为单核心机器而设计的,当时操作系统并不是那么擅长先发制人的多任务处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM