二. goroutine排程器的gmp模型設計思想
參考文獻
以單核作業系統為例,根據時間片輪轉機制,不同的執行緒就要不斷的切換,那麼 執行緒的數量越多,切換成本也就越大,也就越浪費,同樣,多執行緒隨著同步競爭(如鎖、競爭資源衝突等),讓開發變得越來越複雜
而且程序和執行緒占用記憶體比較大
所有面臨的兩個問題,就是 cpu 的高消耗,和 記憶體的 高 占用。
正常的乙個執行緒,是分為使用者空間和核心空間的。
我們可以直接把執行緒的上下兩個部分給直接拆開
給他們起個別名,上邊的就叫協程,通過協程排程器進行控制協程的切換
全域性佇列
:存放等待執行的g
p的本地佇列
:
p列表
m列表
: 當前作業系統分配到 go 程式的核心執行緒數,他不是動態可變的。
利用並行
搶占: 搶占可以理解為,每個cpu
最多分配10ms的時間,每個goroutine
的優先順序都是一樣的。
全域性 g 佇列:當其他的佇列取不到的時候,就從全域性佇列裡取乙個,一般情況下,剛加入的go
會加入到本地佇列裡,而不會加入到全域性佇列中。
偷取工作:
當本執行緒無可用的g
時,嘗試從其他執行緒**的 p 偷取 g,而不是銷毀執行緒。
hand off 傳球
當本執行緒因為g
進行系統呼叫阻塞時,執行緒釋放**的p
,把p
轉移給其他空閒的執行緒執行。
Golang協程排程
有時候可能會出現這種情況,乙個無恥的goroutine阻止其他goroutine執行。當你有乙個不讓排程器執行的 for迴圈時,這就會發生。package main import fmt func main for done fmt.println done for迴圈並不需要是空的。只要它包含了不...
Golang 協程排程
n個使用者空間執行緒在1個核心空間執行緒上執行。優勢是上下文切換非常快但是無法利用多核系統的優點,多個使用者空間執行緒無法並行執行。1個核心空間執行緒執行乙個使用者空間執行緒。這種充分利用了多核系統的優勢但是上下文切換非常慢,因為每一次排程都會在使用者態和核心態之間切換。每個使用者執行緒對應多個核心...
Golang 協程排程
下面看看golang的協程排程 groutine能擁有強大的併發實現是通過gpm排程模型實現,下面就來解釋下goroutine的排程模型。go的排程器內部有三個重要的結構 m,p,g m m是對核心級執行緒的封裝,數量對應真實的cpu數,乙個m就是乙個執行緒,goroutine就是跑在m之上的 m是...