1. 程式人生 > >Windows執行緒基礎

Windows執行緒基礎

Windows為什麼要支援執行緒?

在計算機的早期歲月,作業系統沒有提供執行緒的概念。事實上,整個系統只執行著一個執行執行緒,其中同時包含作業系統程式碼和應用程式程式碼。只用一個執行執行緒的問題在於,長時間執行的任務會阻止其他任務執行。例如,在16位Windows的那些日子,列印一個文件的應用程式很容易“凍結”整個機器,造成OS和其他應用程式停止響應。有的應用程式含有bug,會造成無線迴圈,這同樣會造成整個機器停止工作。

 

所以Microsoft計劃構建一個新的OS來滿足企業和個人的需要。這個新OS必須健壯,可靠,易於伸縮以及安全,而且它必須改進16位Windows的許多不足。

 

Microsoft設計這個OS核心時,他們決定在一個程序(process)中執行應用程式的每個例項。程序不過是應用程式一個例項要使用的資源的集合。每個程序都被賦予了一個虛擬地址空間,確保一個程序使用的程式碼和資料無法被另一個程序訪問。這就確保了應用程式的健壯性。除此以外,OS的核心程式碼和資料是程序無法訪問的,所以應用程式程式碼破壞不了作業系統程式碼和資料。

 

如果機器只有一個CPU,它會執行無線迴圈,不能執行其他任何東西。所以,雖然無法被破壞,而且更安全,但系統仍然可能停止響應。Microsoft需要修正這個問題,他們拿出的方案就是執行緒。執行緒(thread)的職責是對CPU的虛擬化。Windows為每個程序都提供了該程序專用的執行緒(功能相當與一個CPU,可將執行緒理解為一個邏輯CPU)。如果應用程式的程式碼進入無限迴圈,與那個程式碼關聯的程序會“凍結”,但其他程序(它們有自己的執行緒)不會凍結:它們會繼續執行!

 

執行緒開銷

上下文切換

單CPU的計算機一次只能做一件事情。所以Windows必須在系統的所有執行緒(邏輯CPU)之間共享物理CPU。

在任何給定的時刻,Windows只將一個執行緒分配給一個CPU。那個執行緒允許執行一個“時間片”。一旦時間片到期,Windows就上下文切換到另一個執行緒,大概每30ms執行一個上下文切換。Windows通過執行上下文切換,向用戶提供一個健壯的,響應靈敏的作業系統。

 

應該指出的是,安裝多個CPU的計算機課可以真正地同時執行幾個執行緒,這提升了應用程式的可伸縮性(在少量時間裡做更多工作的能力)。Windows為每個CPU核心都分配一個執行緒,每個核心都自己執行到其他執行緒的上下文切換。Windows確保單個執行緒不會同時在多個核心上排程,因為這回帶來巨大的混亂。

 

前臺執行緒和後臺執行緒

CLR將每個執行緒要麼視為前臺執行緒,要麼視為後臺執行緒。一個程序的所有前臺執行緒停止執行時,CLR將強制終止仍在執行的後臺執行緒。這些後臺執行緒會被直接終止,不會丟擲異常。

 

因此,前臺執行緒應該用於執行確實想要完成的任務,比如將資料從記憶體儲存到資料庫。另外,對非關鍵的任務使用後臺執行緒,比如重新計算今天的訂單額度等。這是由於這些工作能在程式重啟後繼續。

CLR要提供前臺執行緒和後臺執行緒的概念來更好地支援AppDomain。每個AppDomain都可以執行一個單獨的應用程式,每個應用程式都有它自己的前臺執行緒。如果一個應用程式退出,造成它前後臺執行緒終止,則CLR仍要保持活動並執行,使其他應用程式繼續執行。

 

應用程式的主執行緒以及通過構造一個Thread物件來顯示建立任何執行緒都預設為前臺執行緒。另一方面,執行緒池預設為後臺執行緒。此外,由進入托管執行環境的本地(native)程式碼建立的任何執行緒都被標記為後臺執行緒。

 

以上內容來自《CLR via C#》