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