Monday, February 05, 2007

Thread Priority and Process Priority

In our walk of life almost of us have done some amount of "multithreading" programming sometime or other and also there are few cases when we have set the "ThreadPrority" level to make sure that the thread gets more/less CPU.

If we look at the "ThreadPriority" enum, we can see there are 5 values ( AboveNormal, BelowNormal,Normal,Highest and Lowest ), a thread’s Priority property determines how much execution time it gets relative to other active threads in the same process, so does that mean if we set the "ThreadPriority" of a thread as "Highest" then the thread will run almost like a realtime application ?

Well NO, setting a thread’s priority to "Highest" doesn’t mean it can perform real-time work, because it’s still limited by the application’s process priority( read "BasePriority"). The Process class has a property named "BasePriority" returns a number which indicates the priority level at which the process is running.

Let us have a look at the internal mechanism, how exactly windows OS work ? the Windows 32-bit operating systems schedule threads using 32 priority levels, numbered from 0 to 31. The highest-numbered thread is processed first. As threads wait to be processed, their priority levels are increased. The base application priority determines the priority level at which threads begin.

For example if a process is running with a "BasePriority" Normal(which is the default value ) and we set the "ThreadPriority" of a thread as "Highest" then the priority level of the thread will be 9( visit this link [http://msdn2.microsoft.com/en-us/library/ms685100.aspx] to see all the combination of Process.BasePriority and Thread.ThreadPriority, it shows the scheduling priority level with respect to the Process.BasePriority and Thread.ThreadPriority ), so if there is any other thread which has higher level ( > 9 in this context), that will run first.

So, to get the expected behavior( say we want to run an application almost like a realtime application which should consume most CPU and there should not be any preempt on this thread)setting the "ThreadProperty" will not be enough, we must set the "Process.BasePriority"accordingly. To set the BasePriority of a Process we have take help of the "PriorityClass" property of the Process class( since Process.BasePriority is a readonly property ).

Sample code:
System.Diagnostics.Process p = System.Diagnostics.Process.GetCurrentProcess(); p.PriorityClass = System.Diagnostics.ProcessPriorityClass.High;

Alternatively we can do the above thru TaskManager also.

Note: As per MSDN documentation we must not set the ProcessPriority as "Realtme" cause that will preempt all other processes( even OS process )which will lead to a machine hang, may be the keyboard and mouse will not work so there should not be any other option other than a hard booting.

No comments: