2013-09-25 47 views
1

在C#中,如果高优先级的任务准备好执行和其他(低优先级)的线程已经是显示器内部,将低优先级的任务在以下两种情况下被抢占:C#,线程优先级,并锁定

  1. 较高优先级任务想要获取由低优先级任务获取的一个(或多个)锁。
  2. 优先级较高的任务不需要由低优先级任务获取的任何锁。

编译器/操作系统是否在任务抢占方面做了任何聪明的事情,还是总是出现优先级较高的任务始终抢占较低优先级的任务?

回答

3

如果更高优先级的线程正在等待锁定,则无论哪个线程拥有锁定,它都不会被调度。

如果更高优先级的线程没有等待任何东西,那么它可以抢占较低优先级的线程。尽管如此,这些都不是真正的.NET或C# - 它确实最终归功于操作系统来管理线程并安排它们。

你可能会发现this MSDN article on thread priorities有用 - 它肯定让我感到惊讶几点。特别是:

系统以循环方式为所有具有最高优先级的线程分配时间片。如果这些线程都没有准备好运行,则系统以循环方式为所有具有次高优先级的线程分配时间片。如果更高优先级的线程可用于运行,则系统将停止执行较低优先级的线程(不允许其使用其时间片完成),并将全时间片分配给较高优先级的线程。

应该可以通过创建一个计划,一些高优先级的线程和一些低优先级的线程来验证;上面的引用表明,如果你可以保持处理器忙于高优先级的线程,那么低优先级的线程将完全饿死。这令我感到惊讶,但你应该能够尝试并看看会发生什么。试着保持高优先级的线程忙于工作,不能导致任何IO(等),否则会阻止他们。

2

对于那些谁感兴趣的问题的第一个场景,下面是一个实验我做了测试线程抢先与锁定打交道时:

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! 
     } 
    } 

以下是该程序的输出:

低优先级任务执行

低优先级的任务将不会释放锁!

高优先级任务执行

虽然高优先级任务需要获取resourcelock为了它来执行(这已经是由低优先级任务获得),高优先级任务被执行死刑只是为了找出它不能执行!因此,编译器不会进行任何优化,以防止在任务需要执行资源时进行不必要的上下文切换。