2013-09-25 49 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爲了它來執行(這已經是由低優先級任務獲得),高優先級任務被執行死刑只是爲了找出它不能執行!因此,編譯器不會進行任何優化,以防止在任務需要執行資源時進行不必要的上下文切換。