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