首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

深入探討 .NET 多線程與並行計算(十二):CLR via C# 第三版閱讀筆記(上)

     編輯:關於ASP.NET

為何線程被視為昂貴資源?

《CLR via C#》第三版剛出版,書中關於線程章節的見解彌補了我過去的知識盲區,因此將關鍵點整理成此系列文章。作者身為微軟顧問,不僅傳授 MSDN 教條,更分享獨到見解,甚至指出 .NET 框架的不足並給出自行實現方案,這正是我推崇此書的原因。

1. 記憶體開銷驚人

以 32 位架構為例,每個線程包含:線程內核對象(約 700 位元組)、線程環境塊(4 KB)、內核堆疊(12 KB)以及使用者堆疊(1 MB)。值得注意的是,這 1 MB 使用者堆疊在 CLR 建立線程時一次性配置完畢,並非動態增長(Windows 僅保留 1 MB 位址空間)。

2. 線程切換的高昂代價

線程切換需完成三大步驟:將 CPU 暫存器值存入當前線程內核對象;若切換至不同 CPU,需準備新的虛擬位址空間;最後將目標線程內核對象中的暫存器值複製回 CPU 暫存器。

3. 快取失效帶來的效能損耗

更大的效能傷害源於線程切換後,CPU 快取中的資料可能無法命中,迫使重新載入資料,這在高頻切換場景下尤為明顯。

4. 垃圾回收時的全線程暫停

GC 發生時,CLR 會暫停所有線程、掃描線程堆疊、壓縮堆疊並重設指標位址,線程越多,暫停時間越長。

雖然線程比進程輕量,但 Outlook 就有數十個線程,甚至記事本的「開啟檔案」對話框也能產生 22 個線程(Vista 為避免阻塞 UI,大量使用新線程載入內容)。目前 CLR 線程一對一對應 Windows 線程,作者期盼未來 CLR 能實現虛擬邏輯線程以改善效能。

何時應手動建立線程而非使用線程池?

  1. 需自訂優先權:線程池線程固定為 Normal。
  2. 需前台線程:線程池線程皆為背景線程。建議非 UI 線程設為背景線程,否則關閉 UI 後進程可能殘留佔用記憶體。
  3. 需手動中止線程:線程池不提供此功能。
  4. 長時間執行的任務:線程池適合短小精悍的任務,長任務會佔用池資源導致飢餓。

線程排程機制

  1. 線程優先權範圍 0~31,高優先權線程一就緒即搶佔 CPU,Windows 會將最高優先權線程分派至各 CPU 核心並行執行。
  2. 進程有 6 個優先等級,線程有 7 個,組合映射為實際優先權 0~30(0 保留給系統記憶體釋放)。CLR 僅開放 5 個等級供開發者設定。
  3. 進程優先權本質是虛擬概念,用於映射線程優先權。大多數進程由 Explorer 啟動,預設為 Normal,故線程實際優先權多落在 6~10 之間。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved