一文詳解golang中的gmp模型
誕生
(我們?yōu)槭裁葱枰猤mp模型)
我們知道,早期的操作系統(tǒng)操作系統(tǒng)是單進程的。后來引入了并發(fā)的思想,發(fā)展為多進程/多線程操作系統(tǒng),操作系統(tǒng)可以通過時間片在多個進程之間切換。然而,在多個進程之間進行切換,是需要切換成本的。
在引入?yún)f(xié)程之前,我們需要回顧一下進程和線程的概念。
進程,是軟件的執(zhí)行副本,是分配資源的基礎(chǔ)單位。每個進程有自己的進程控制塊,代碼,數(shù)據(jù)。
線程,是輕量級的線程,是調(diào)度和執(zhí)行的基本單位。(這里單指內(nèi)核態(tài)線程),每個線程有自己的寄存器和棧。
時間與空間
在傳統(tǒng)的多線程并發(fā)模型中,輕量級的線程只需進行寄存器和棧等上下文的切換就可以完成多個任務(wù)的并發(fā)執(zhí)行。然而,隨著并發(fā)量越來越高,有些局限性開始展現(xiàn)出來。
隨著并發(fā)量的上漲,切換的頻率越來越高,線程的切換開銷開始顯露不足
隨著并發(fā)量的上漲,需要越來越多的線程,內(nèi)存占用也越來越大
因此,在高并發(fā)的需求下,協(xié)程因此誕生了,也就是golang中的groutine。
在時間上,平均每次協(xié)程切換的開銷是 120ns 左右,相對于進程切換的開銷大約 3.5us,大約是其的三十分之一
在空間上,協(xié)程初始化創(chuàng)建的時候為其分配的棧有 2KB,而線程棧一般在4-8M左右。
那么,為什么協(xié)程可以這么輕量呢。
在傳統(tǒng)的多線程中,線程與進程的關(guān)系是固定的,每個線程必定從屬于一個進程。而到了協(xié)程,為了去掉更多的枷鎖,協(xié)程是不依賴于某個固定的線程的,協(xié)程可以自由切換而不比。換而言之,golang在用戶空間與內(nèi)核空間之間創(chuàng)建了一層新的映射,而這,就是gmp模型。
概念
(gmp是什么)
gmp=groutine+machine+processor
G
- (1) g 即goroutine,是golang中對協(xié)程的抽象;
- (2) g有自己的運行棧、狀態(tài)、以及執(zhí)行的任務(wù)函數(shù)(用戶通過go func指定);
- (3) g需要綁定到p才能執(zhí)行,在g的視角中,p就是它的cpu.
M
- (1) m 即machine,是golang 中對線程的抽象;
- (2) m的數(shù)量是動態(tài)的,golang語言中默認最大值為10000,也可以用runtime/debug包中的SetMaxThreads函數(shù)來設(shè)置
- (3) ?個M阻塞,會創(chuàng)建?個新的M。如果有M空閑,那么就會回收或者睡眠。
P
- (1) p即 processor,是golang 中的調(diào)度器;
- (2) p是 gmp的中樞,借由p承上啟下,實現(xiàn)g 和m之間的動態(tài)有機結(jié)合;
- (3)對g而言,p是其cpu,g只有被p調(diào)度,才得以執(zhí)行;
- (4)對m而言,p是其執(zhí)行代理,為其提供必要信息的同時(可執(zhí)行的g、內(nèi)存分配情況等),并隱藏了繁雜的調(diào)度細節(jié);
- (5) p 的數(shù)量決定了g最大并行數(shù)量,可由用戶通過GOMAXPROCS進行設(shè)定(超過CPu核數(shù)時無意義).也可以在程序中通過runtime.GOMAXPROCS() 來設(shè)置
gmp模型圖片
調(diào)度
調(diào)度策略1 work steal
自己的本地隊列為空時,會去別的本地隊列偷取一半,保證有任務(wù)可以執(zhí)行。
調(diào)度策略2 hand off
當一個綁定了M的G發(fā)生阻塞,會創(chuàng)建/喚醒
調(diào)度策略3 并行
最多有GOMAXPROCS個線程分布在多個CPU上同時運?
調(diào)度策略4 搶占
在Go中,?個goroutine最多占?CPU 10ms,防?其他goroutine被餓死
調(diào)度策略5 全局隊列
當M執(zhí)?work stealing從其他P偷不到G時,它可以從全局G隊列獲取G。
以上就是詳解golang中的gmp模型的詳細內(nèi)容,更多關(guān)于詳解golang中的gmp模型的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
golang常用庫之pkg/errors包第三方錯誤處理包案例詳解
這篇文章主要介紹了golang常用庫之pkg/errors包第三方錯誤處理包,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03Golang報“import cycle not allowed”錯誤的2種解決方法
這篇文章主要給大家介紹了關(guān)于Golang報"import cycle not allowed"錯誤的2種解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以們下面隨著小編來一起看看吧2018-08-08