《CLR via C#》之線程處理——線程基礎
windows為什么要支持線程
線程開銷
CPU發展趨勢
CLR線程和Windows線程
使用專用線程執行異步的計算限制操作
線程調度和優先級
windows為什么要支持線程
早期的操作系統只有一個執行線程,但同時包含了操作系統代碼和應用程序代碼,一旦應用程序出現bug,整個主機必須重啟,數據都會丟失。
微軟后來發布了新的內核——Windows NT。決定在一個進程中運行應用程序的實例。進程實際是應用程序實例需要使用的資源的集合。保護了數據的安全性。但是如果發生死循環呢?如果機器只有一個CPU,他會執行死循環,雖然數據不會被破壞,系統依然會停止響應。微軟的解決方案就是線程。它的職責是對CPU進行了虛擬化。每個進程都有專用的線程(相當于一個CPU)。
線程開銷
和一切虛擬化機制一樣,線程有空間(內存耗用)和時間(運行時的執行性能)上的開銷:
- 線程內核對象(thread kernel object)
為每個線程分配的數據結構之一。包括描述線程的一組屬性,線程上下文(CPU寄存器集合)。x86,x64,ARM CPU架構,上下文分別占約700,1240,350字節。 - 線程環境塊(thread environment block, TEB)
TEB是用戶模式中分配和初始化的內存塊,占用一個內存頁(三種架構都是4kB)。 - 用戶模式棧(user-model stack)
存儲傳給方法的局部變量和實參。Windows默認分配1MB內存(保留地址空間,需要時換到物理內存。 - 內核模式棧(kernel-model stack)
用于向OS內核模式函數傳遞實參。Win32:12KB;Win 64:24KB。 - DLL線程連接(attach)和線程分離(detach)通知
Windows的一個策略是,任何進程在創建和終止線程時,都會調用進程加載的所有非托管DLL的DLLMain方法。
上下文切換開銷
Windows大約每30ms執行一次上下文切換。這個動作不會帶來任何內存或性能上的收益。事實上,上下文切換可能帶來其它的性能損失,比如缺頁中斷,cache寫入。
執行GC時,CLR必須掛起所有線程,遍歷它們的棧查找根以便對堆中的對象進行標記(GC算法第一步),再次遍歷它們的棧(更新它們的根),再恢復所有線程。所以減少線程的數量會顯著提升GC的性能。
線程越多,調試體驗越差(遇到斷點時掛起所有線程)。
CPU發展趨勢
除了提高CPU的速度外,還有多核——為了使用線程。
目前的三種多CPU技術:
- 多個CPU;
- 超線程CPU——芯片中包含兩組架構狀態,比如CPU寄存器,但只要一組執行資源;
- 多核CPU。
CLR線程和Windows線程
目前,CLR線程完全等價于Windows線程。
使用專用線程執行異步的計算限制操作
應盡量使用線程池來執行異步的計算操作。但是如果滿足以下任何條件,就可顯式創建自己的線程。
- 線程需要非Normal的優先級運行。
- 需要線程是一個前臺線程,防止應用程序在線程結束前終止。
- 直接為長時間運行的任務創建專用線程。因為,線程池為了判斷是否需要創建一個額外的線程,所采用的邏輯比較復雜。
- 需要控制線程(啟動,并可能調用Abort方法)。
線程調度和優先級
Windows是搶占式多線程操作系統,所有你不能保證自己的線程一直運行,也阻止不了其它線程的運行。
Microsoft知道開發人員 在為線程分配優先級時很難做到完全合理,因此公開了優先級系統的一個抽象層。
- 進程優先級類(抽象概念):決定應用程序與其它應用相比的響應能力。
6個進程優先級類:Idle,Below Normal,Normal(默認),Above Normal,High(絕對必要時使用),和Realtime(盡量避免使用)。 - 優先級:線程優先級
Windows支持7個相對線程優先級:Idle,Lowest,Below Normal,Normal,Above Normal,Highest和Time-Critical
每個線程的優先級取決于兩個標準:1)它的進程優先級類;2)在其進程優先級類中,線程的優先級。他倆合并構成一個線程的“基礎優先級”。每個線程都有一個“動態優先級”,線程調度器根據 這個優先級決定執行哪個線程。最初,基礎優先級和動態優先級相同。系統可以提升基礎優先級在0到15之間的線程優先級(即,概念上非Realtime優先級類)。
事實上,Windows永遠不會調度進程,它只調度線程。
C#可以通過設置Thread的Property屬性,來設置相對線程優先級。ThreadPriority枚舉:Lowest,BelowNormal,Normal,AboveNormal或者Highest。和Windows為自己保留了優先級0和Realtime范圍一樣,CLR為自己保留了Idle和Time-Critical優先級。