4

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

DayDayHappy
  • 1,679
  • 1
  • 15
  • 26
  • Processes can't uses each others Threadpool, I assume you mean Process == Thread. – H H Jun 25 '15 at 09:02

3 Answers3

5

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. In Windows process' priority is given by its class (from IDLE_PRIORITY_CLASS to REALTIME_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.

From 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). 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. 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(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). This is just one issue, please refer to MSDN for more details (increasing thread's priority may even result is worse performance).

Community
  • 1
  • 1
Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
1

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.

H H
  • 263,252
  • 30
  • 330
  • 514
0

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 (e.g. one is blocking the other). And of course, any time something is blocking on the threadpool, you're wasting resources :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 :)

You'll find a lot of nice explanations on the internet - for example, 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.

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • thank you. but if I run my job more than 1 hour with 100% cpu, i must have another unnecessary bigger problem : > – DayDayHappy Jun 25 '15 at 09:08
  • @DayDayHappy Yup, usually. A profiler could help you with determining that - I've seen bits of code that took a long amount of time while taking 100% of the CPU that only did so because of poor multi-threading. That said, if the consumption is natural, there's little wrong with 100% CPU usage - modern OS and CPU can usually handle it without hurting system performance as a whole. You could always add throttling if you really want to, but it shouldn't really be necessary. Thread priorities are more likely to hurt than help - the scheduler really works the best when everyone is Normal :D – Luaan Jun 25 '15 at 09:16
  • true. 99% of my habit is to lower my process priority because I want to give way to others as I know my task is long running and it is allowed to run unexpectedly longer. thanks – DayDayHappy Jun 25 '15 at 09:25
  • @DayDayHappy Yeah, I understand that perfectly - it used to be a very nice defensive way of coding back on Windows 3.1 (and to a lesser extent, the 95 family). It doesn't really help on NT, usually. The fun part is that even then, it was mostly useful because the other applications were written incorrectly (including managing their thread/process priorities wrong). In fact, that's one of the reasons why pre-emptive multi-threading was added in the first place - to prevent a badly written application from killing/freezing your whole system :D – Luaan Jun 25 '15 at 09:27