Go并發(fā)編程-線程模型

在介紹Go獨特的線程模型之前,我們先來回顧下常見的三種線程模型。
線程的并發(fā)執(zhí)行是由操作系統(tǒng)來進行調(diào)度的,操作系統(tǒng)在內(nèi)核提供對線程的支持。而我們在使用高級語言編寫程序時候創(chuàng)建的線程屬于用戶線程,那么用戶線程與內(nèi)核線程是什么關系呢?根據(jù)用戶線程與內(nèi)核線程關系的不同可以分成三類:

  1. 一對一模型(1 : 1):每個用戶級線程映射到一個內(nèi)核線程。
    一對一模型(1 : 1)

優(yōu)點:

  • 在多核處理器下,內(nèi)核空間線程模型支持了真正的并行。
  • 當一個線程被阻塞后,另一個線程繼續(xù)執(zhí)行,所以并發(fā)能力較強。

缺點:

  • 每創(chuàng)建一個用戶線程都需要創(chuàng)建一個內(nèi)核線程與之對應,這樣創(chuàng)建線程的開銷比較大,會影響到應用程序的性能。
  • 由于操作系統(tǒng)一般會限制內(nèi)核線程的個數(shù),所以用戶線程的個數(shù)會受到限制。
  • 另外由于用戶線程與內(nèi)核線程一一對應,當用戶線程執(zhí)行系統(tǒng)調(diào)用(比如IO操作)的時候,需要從用戶態(tài)切換到內(nèi)核態(tài)執(zhí)行內(nèi)核操作,然后等執(zhí)行完畢后又會從內(nèi)核態(tài)切換到用戶態(tài)執(zhí)行用戶程序,而這個切換操作開銷是相對比較大的。
  1. 多對一模型(M : 1):多個用戶線程映射到一個內(nèi)核線程,線程管理在用戶空間完成。
    多對一模型(M : 1)

優(yōu)點:

  • 線程上下文切換都發(fā)生在用戶空間,避免模態(tài)切換(mode switch),所以切換速度很快,開銷很小。
  • 可創(chuàng)建的用戶線程的數(shù)量可以很多,只受內(nèi)存大小限制。

缺點:

  • 由于多個用戶線程對應一個內(nèi)核線程,多核處理器得不到充分地利用。
  • 由于多個用戶線程對應一個內(nèi)核線程,當該內(nèi)核線程對應的一個用戶線程被阻塞掛起時候,該內(nèi)核線程對應的其他用戶線程也不能運行了,因為這時候內(nèi)核線程已經(jīng)被阻塞掛起了。
  1. 多對多模型(M : N):用戶線程和內(nèi)核線程的數(shù)量比為 M : N。
    多對多模型(M : N)

優(yōu)點:

  • 每個內(nèi)核線程對應多個用戶線程,每個用戶線程也可以對應多個內(nèi)核線程。當一個用戶線程阻塞后,其對應的內(nèi)核線程會被阻塞,但是被阻塞的內(nèi)核線程對應的其他用戶線程可以切換到其他的內(nèi)核線程上繼續(xù)運行,所以多對多模型是可以充分利用多核CPU提升運行效率。
  • 多對多模型對用戶線程個數(shù)沒有限制,理論上只要內(nèi)存夠用可以無限創(chuàng)建。

Go實現(xiàn)的是多對多模型(M : N)。在操作系統(tǒng)提供的內(nèi)核線程之上,Go搭建了一個特有的兩級線程模型。一級是操作系統(tǒng)的調(diào)度系統(tǒng),該調(diào)度系統(tǒng)調(diào)度邏輯處理器占用cpu時間片運行;另一級是Go的運行時調(diào)度系統(tǒng),該調(diào)度系統(tǒng)調(diào)度某個goroutine在邏輯處理上運行。

說起Go的線程實現(xiàn)模型,有三個必知的核心元素,它們支撐起了這個模型的主框架。
M:Machine的縮寫。一個M代表一個內(nèi)核線程,或者“工作線程”。
P:Processor的縮寫。一個P代表執(zhí)行一個Go代碼片段所必需的資源(或稱“上下文環(huán)境”)。
G:Goroutine的縮寫。一個G代表一個Go代碼片段。前者是對后者的一種封裝。

簡單來說,一個G的執(zhí)行需要P和M的支持。
一個M在與一個P關聯(lián)之后,就形成了一個有效的G運行環(huán)境(內(nèi)核線程+上下文環(huán)境)。
每個P都會包含一個可運行的G的隊列(runq)。該隊列中的G會被依次傳遞給與P關聯(lián)的M,并獲得運行時機。
MPG之間的關系如下圖所示:


Go線程模型

可以看到,M與KSE之間總是一對一的關系,一個M能且僅能代表一個內(nèi)核線程。Go的運行時系統(tǒng)(runtime system)用M代表一個內(nèi)核調(diào)度實體。M與KSE之間的關聯(lián)非常穩(wěn)固,一個M在其生命周期內(nèi),會且僅會與一個KSE產(chǎn)生關聯(lián)。相比之下,M與P、P與G之間的關聯(lián)都是易變的,它們之間的關系會在實際調(diào)度的過程中發(fā)生變化。此外,M與G之間也會建立關聯(lián),因為一個G終歸會由一個M來負責運行;它們之間的關聯(lián)會由P來牽線。注意,由于M、P和G之間的關系在實際調(diào)度過程中多變,上圖中的可能關聯(lián)僅能作為一般性的示意。

至此,我們已經(jīng)知道了這些核心實體之間可能存在的關系。Go的運行時系統(tǒng)會對這些實體的實例進行實時管理和調(diào)度。接下來,我們分三篇文章分別介紹M, P, G的內(nèi)容。

相關鏈接:
Go并發(fā)編程-線程模型
Go并發(fā)編程-線程模型(M)
Go并發(fā)編程-線程模型(P)
Go并發(fā)編程-線程模型(G)

參考資料:
http://www.itdecent.cn/p/2e45a5c0b72f
https://blog.csdn.net/m0_37055174/article/details/104132303
https://www.ituring.com.cn/book/tupubarticle/16048

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

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