天天看點

MPG線程模型簡介

概述

go語言中的MPG線程模型對兩級線程模型進行了一定程度的改進,使它能夠更加靈活的進行線程之間的排程。

它由3個主要子產品構成,如下圖:

MPG線程模型簡介

MPG的3個主要子產品以及功能,我們通過下表所示。

子產品 功能說明
Machine 一個Machine對應一個核心線程,相當于核心線程在go語言中的映射
Processor 一個Processor表示執行go代碼片段的所必需的上下文環境,可以了解為使用者代碼邏輯的處理器
Goroutine 是對go語言中代碼片段的封裝,其實是一種輕量級的使用者線程

為了更加形象,下面的介紹中我們會用M、P、G分别指代Machine、Processor和Goroutine。從圖4-4可以看出,每一個

M都會與一個核心線程綁定,在運作時一個M同時隻綁定一個P,而P和G的關系則是一對多。在運作過程中,M和核心線程之間

對應關系不會變化,在M的生命周期内,它隻會與一個核心線程綁定,而M和P以及P和G之間的關系都是動态可變的。

在實際的運作過程中,M和P的組合才能夠為G提供有效的運作環境,而多個可執行G将會順序排成一個隊列挂在某個P上面,

等待排程和執行,如圖所示。

MPG線程模型簡介

上圖中,M和P共同構成了一個基本的運作環境,此時G0中的代碼片段處于正在運作的狀态,而右邊的G隊列處于待執行狀态。

當沒有足夠的M來和P組合為G提供運作環境時,Go語言會建立新的M。在很多時候M的數量可能會比P要多。在單個go語言程序中,

P的最大數量決定了程式的并發規模,且P的最大數量是由程式決定的。可以通過修改環境變量GOMAXPROCS和調用函數runtime.GOMAXPROCS

來設定P的最大值。

M和P會适時的組合和斷開,以保證待執行G隊列能夠得到及時運作。比如說圖4-5中的G0此時因為網絡I/O而阻塞了M,那麼P就會攜帶剩餘的

G投入到其他M中。這個新的M(M1)可能是新建立的,也可能是從排程器空閑M清單中擷取的,這取決于此時的排程器空閑M清單中是否存在M,

這樣的機制設計也是為了避免M過多建立。運作機制如圖所示

MPG線程模型簡介

當M對應的核心線程被喚醒時,M将會嘗試為G0捕獲一個P上下文,可能是從排程器的空閑P清單中擷取,如果擷取不成功,

M會把G0放入到排程器的可執行G隊列中,等待其他P的查找。為了保證G的均衡執行,非空閑的P運作完自身的可執行G隊列後,

會周期性從排程器的可執行G隊列中擷取待執行的G,甚至從其他的P的可執行G隊列中掠奪G。

-------------------------------------------