2018-12-02

線程模型

內(nèi)核級(jí)線程模型(KSE(Kernel Scheduling Entity))

關(guān)鍵點(diǎn): 完全靠操作系統(tǒng)調(diào)度

每一個(gè)用戶線程綁定一個(gè)實(shí)際的內(nèi)核線程,而線程的調(diào)度則完全交付給操作系統(tǒng)內(nèi)核去做,應(yīng)用程序?qū)€程的創(chuàng)建、終止以及同步都基于內(nèi)核提供的系統(tǒng)調(diào)用來(lái)完成

用戶級(jí)線程模型

關(guān)鍵點(diǎn): 完全靠自己調(diào)度

用戶線程與內(nèi)核線程KSE是多對(duì)一(N : 1)的映射模型,多個(gè)用戶線程的一般從屬于 單個(gè)進(jìn)程 的調(diào)度是由用戶自己的線程庫(kù)來(lái)完成,線程的創(chuàng)建、銷毀以及多線程之間的協(xié)調(diào)等操作都是由用戶自己的線程庫(kù)來(lái)負(fù)責(zé)而無(wú)須借助系統(tǒng)調(diào)用來(lái)實(shí)現(xiàn)。操作系統(tǒng)只知道用戶進(jìn)程而對(duì)其中的線程是無(wú)感知的,內(nèi)核的所有調(diào)度都是基于用戶進(jìn)程。

兩級(jí)(混合型)線程模型

關(guān)鍵點(diǎn): 自身調(diào)度與系統(tǒng)調(diào)度協(xié)同工作

用戶線程與內(nèi)核KSE是多對(duì)多(N : M)的映射模型:

首先,區(qū)別于用戶級(jí)線程模型,兩級(jí)線程模型中的一個(gè)進(jìn)程可以與多個(gè)內(nèi)核線程KSE關(guān)聯(lián),于是進(jìn)程內(nèi)的多個(gè)線程可以綁定不同的KSE,這點(diǎn)和內(nèi)核級(jí)線程模型相似;

其次,又區(qū)別于內(nèi)核級(jí)線程模型,它的進(jìn)程里的所有線程并不與KSE一一綁定,而是可以動(dòng)態(tài)綁定不同KSE, 當(dāng)某個(gè)KSE因?yàn)槠浣壎ǖ木€程的阻塞操作被內(nèi)核調(diào)度出CPU時(shí),其關(guān)聯(lián)的進(jìn)程中其余用戶線程可以重新與其他KSE綁定運(yùn)行

GPM模型

基本概念

OS線程抽象,代表著真正執(zhí)行計(jì)算的資源, 每一個(gè) goroutine 實(shí)際上就是在 M 中執(zhí)行, M 的數(shù)量目前最多 10000 個(gè).

M 并不保存 G 的狀態(tài), 與 G 本身并沒(méi)有關(guān)系, 所以 G 可以在不同的 M 執(zhí)行

分配程序執(zhí)行的上下文環(huán)境, 數(shù)量 <= 內(nèi)核數(shù)量, 即同時(shí)能夠并行執(zhí)行的 G 的數(shù)量,相對(duì)于 G 而言, P的角色相當(dāng)于CPU.

程序代碼中的每一次使用關(guān)鍵字 go 執(zhí)行函數(shù)其實(shí)都生成了一個(gè) G ,并將之加入到本地的 G 隊(duì)列中, 之后 M 會(huì)生成 G 執(zhí)行的上下文也就是綁定 P 來(lái)執(zhí)行函數(shù).

G 維護(hù)者goroutine需要的棧、程序計(jì)數(shù)器以及它所在的M等信息。

  • Seched

代表著一個(gè)調(diào)度器 它維護(hù)有存儲(chǔ)空閑的 M 隊(duì)列和空閑的 P 隊(duì)列,可運(yùn)行的 G 隊(duì)列,自由的 G 隊(duì)列以及調(diào)度器的一些狀態(tài)信息等。

模型調(diào)度

[圖片上傳失敗...(image-401ce0-1543731894810)]

  1. P 如何獲得 G
    調(diào)度器 Seched 生成一個(gè) M , 然后 M 需要持有(綁定)一個(gè) P ,接著 M 會(huì)啟動(dòng)一個(gè)OS線程,循環(huán)讓 P 會(huì)首先從自己的本地隊(duì)列(Local Quequ)中取可執(zhí)行(Runnable)的 G 執(zhí)行, 如果本地隊(duì)列中沒(méi)有, 則會(huì)從全局隊(duì)列(Globle Queue)中取 G , 如果還沒(méi)有, 則會(huì)從其他的 P 的本地隊(duì)列中取一半的隊(duì)列放入自己本地隊(duì)列之中

  2. M 執(zhí)行函數(shù)遇到阻塞,如何處理

實(shí)際代碼執(zhí)行中可能存在下面的問(wèn)題,導(dǎo)致程序阻塞

<pre class="prettyprint hljs perl" style="box-sizing: border-box; overflow: auto; font-family: monospace, monospace; font-size: 10px; display: block; padding: 0.5em; color: rgb(171, 178, 191); background: rgb(40, 44, 52); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">blocking syscall (for example opening a file)
network input
channel operations
primitives in the sync package</pre>

主要可歸為兩類

  • 用戶態(tài)阻塞/喚醒

當(dāng) goroutine 因?yàn)閏hannel操作或者network I/O而阻塞時(shí)(實(shí)際上golang已經(jīng)用netpoller實(shí)現(xiàn)了goroutine網(wǎng)絡(luò)I/O阻塞不會(huì)導(dǎo)致M被阻塞,僅阻塞G,這里僅僅是舉個(gè)栗子),對(duì)應(yīng)的G會(huì)被放置到某個(gè) wait 隊(duì)列(如channel的waitq),該G的狀態(tài)由 _Gruning 變?yōu)?_Gwaitting ,而M會(huì)跳過(guò)該G嘗試獲取并執(zhí)行下一個(gè)G,如果此時(shí)沒(méi)有runnable的G供M運(yùn)行,那么M將解綁P,并進(jìn)入 sleep 狀態(tài);當(dāng)阻塞的G被另一端的G2喚醒時(shí)(比如channel的可讀/寫(xiě)通知),G被標(biāo)記為runnable,嘗試加入G2所在P的runnext,然后再是P的Local隊(duì)列和Global隊(duì)列。

  • 系統(tǒng)調(diào)用阻塞

當(dāng)G被阻塞在某個(gè)系統(tǒng)調(diào)用上時(shí),此時(shí)G會(huì)阻塞在 _Gsyscall 狀態(tài),M也處于 block on syscall 狀態(tài),此時(shí)的M可被搶占調(diào)度:執(zhí)行該G的M會(huì)與P解綁,而P則嘗試與其它 idle 的M綁定,繼續(xù)執(zhí)行其它G。如果沒(méi)有其它 idle 的M,但P的Local隊(duì)列中仍然有G需要執(zhí)行,則創(chuàng)建一個(gè)新的M;當(dāng)系統(tǒng)調(diào)用完成后,G會(huì)重新嘗試獲取一個(gè) idle 的P進(jìn)入它的Local隊(duì)列恢復(fù)執(zhí)行,如果沒(méi)有idle的P,G會(huì)被標(biāo)記為runnable加入到Global隊(duì)列。

調(diào)度使用了名叫 work stealing 的算法, 這種算法適用場(chǎng)景是任務(wù)之間的耗時(shí)相差比較大,即有的任務(wù)很耗時(shí),有的任務(wù)很快完成,用這種用算法很合適;如果任務(wù)的耗時(shí)很平均則不適合,因?yàn)楦`取任務(wù)也是需要搶占鎖的,會(huì)造成額外的消耗。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容