Reputation: 301
In C#, if a high priority task is ready to execute and another (low priority) thread is already inside a monitor, would the low priority task be preempted in the following two scenarios:
Do the compiler/OS do anything clever in regards to task preemption or is it always the case that higher priority tasks always preempt lower priority tasks?
Upvotes: 3
Views: 2477
Reputation: 301
For those who are interested in the first scenario of the question, the following is an experiment I did to test thread preemption when dealing with locking:
object resourselock = new object();
public void Test()
{
Thread lowestThread = new Thread(new ThreadStart(Low));
lowestThread.Priority = ThreadPriority.Lowest;
Thread highestThread = new Thread(new ThreadStart(High));
highestThread.Priority = ThreadPriority.Highest;
lowestThread.Start();
Thread.Sleep(1000); //makes sure that the lowest priority thread starts first
highestThread.Start();
}
public void Low()
{
Console.WriteLine("Low priority task executed");
lock (resourselock)
{
Console.WriteLine("Low priority task will never release the lock!");
while (true) ; //infinite empty statement!
}
}
public void High()
{
System.Console.WriteLine("High priority task executed");
lock (resourselock)
{
System.Console.WriteLine("High priority task got the lock!"); //this will never be reached!
}
}
The following is the output of the program:
Low priority task executed
Low priority task will never release the lock!
High priority task executed
Although the high priority task needs to acquire the resourcelock (which is already acquired by the low priority task) in order for it to execute, the high priority task was executed just to find out it cannot execute!! Thus, there is no optimization whatsoever done by the compiler to prevent unnecessary context-switches when tasks need resources to execute.
Upvotes: 6
Reputation: 1500555
If the higher priority thread is waiting for a lock, regardless of which thread owns the lock, it won't be scheduled.
If the higher priority thread isn't waiting for anything, then it may preempt a lower priority thread. None of this is really .NET or C# specific though - it really ends up being down to the operating system to manage the threads and schedule them.
You might find this MSDN article on thread priorities useful - it certainly surprised me on a few points. In particular:
The system assigns time slices in a round-robin fashion to all threads with the highest priority. If none of these threads are ready to run, the system assigns time slices in a round-robin fashion to all threads with the next highest priority. If a higher-priority thread becomes available to run, the system ceases to execute the lower-priority thread (without allowing it to finish using its time slice), and assigns a full time slice to the higher-priority thread.
You should be able to verify that by creating a program which some high priority threads and some low priority threads; the above quote would suggest that if you can keep the processor busy with the high priority threads, the low priority threads will starve completely. That surprises me, but you should be able to experiment and see what happens. Just try to keep the high priority threads busy with work that can't cause any IO (etc) which would otherwise stall them.
Upvotes: 4