協(xié)程細(xì)節(jié)G-P-M模型

模型概述

1 .每一個(gè)os線程都有一個(gè)固定各大小的內(nèi)存塊來做棧大磺,這個(gè)棧會(huì)用來存儲(chǔ)當(dāng)前正在被調(diào)用或者掛起的的函數(shù)內(nèi)部變量
2 .這個(gè)棧是可大可小的,2M對(duì)于一個(gè)小的goroutine來說是很大的探膊,但是對(duì)于一個(gè)復(fù)雜任務(wù)來說又是很小的杠愧。所以設(shè)計(jì)成是可擴(kuò)展的。
3 .在go中逞壁,每一個(gè)goroutine是一個(gè)獨(dú)立的執(zhí)行單元流济,相對(duì)于每個(gè)os線程固定分配的2M大小,goroutine的棧采用了動(dòng)態(tài)擴(kuò)容的方式腌闯,初始大小僅為2kb绳瘟,隨著任務(wù)執(zhí)行按需增長,最大可達(dá)1GB,而且完全由go自己的調(diào)度器來實(shí)現(xiàn)調(diào)度
4.此外姿骏,GC還會(huì)周期性的將不在使用的內(nèi)存回收糖声,收縮棧空間工腋。
5.任何用戶線程最中肯定是需要由OS線程來執(zhí)行的姨丈,但是G并不是直接綁定os線程運(yùn)行,而是使用P來作為兩者的中介
6 .

線程模型

1 .線程是處理器調(diào)度和分配的基本單位擅腰,線程是進(jìn)程內(nèi)部的一個(gè)執(zhí)行單元蟋恬,每個(gè)進(jìn)程至少有一個(gè)主執(zhí)行線程,無需用戶主動(dòng)創(chuàng)建趁冈,是由系統(tǒng)創(chuàng)建的歼争,用戶需要的是在應(yīng)用程序內(nèi)部創(chuàng)建其他線程拜马,多個(gè)線程并發(fā)的運(yùn)行與一個(gè)進(jìn)程中
2 .進(jìn)程是資源擁有的基本單位。每個(gè)進(jìn)程是由私有的虛擬地址空間沐绒,代碼俩莽,數(shù)據(jù)和其他各種系統(tǒng)資源組成
3 .語言的并發(fā)模型,到了操作系統(tǒng)層面乔遮,一定是以線程形態(tài)存在的扮超。
4 .線程可以看成是進(jìn)程中的控制流,一個(gè)進(jìn)程至少會(huì)包含一個(gè)線程蹋肮,因?yàn)槠渲兄辽儆幸粋€(gè)控制流持續(xù)運(yùn)行
5 .一個(gè)進(jìn)程的第一個(gè)線程一定會(huì)隨著這個(gè)進(jìn)程的啟動(dòng)而創(chuàng)建出刷,創(chuàng)建的方法就是系統(tǒng)調(diào)用pthread create函數(shù)
6 .擁有多個(gè)線程的進(jìn)程可以并發(fā)執(zhí)行多個(gè)任務(wù),如果某個(gè)任務(wù)被阻塞坯辩,也不會(huì)影響其他任務(wù)的正常執(zhí)行馁龟。
7 .線程不能獨(dú)立于進(jìn)程存在,他的生命周期不能逾越所屬的進(jìn)程的生命周期
8 .事實(shí)上Go調(diào)度器有一個(gè)復(fù)用機(jī)制漆魔,每次使用go關(guān)鍵字的時(shí)候它會(huì)檢查當(dāng)前結(jié)構(gòu)體M中的P中坷檩,是否有可用的結(jié)構(gòu)體G。如果有改抡,則直接從中取一個(gè)矢炼,否則,需要分配一個(gè)新的結(jié)構(gòu)體G雀摘。如果分配了新的G裸删,需要將它掛到runtime的相關(guān)隊(duì)列中,但是調(diào)度器卻沒有限制goroutine的數(shù)量阵赠,這在瞬時(shí)性goroutine爆發(fā)的場(chǎng)景下就可能來不及復(fù)用G而依然創(chuàng)建了大量的goroutine涯塔,

進(jìn)程

1 .正在執(zhí)行的程序。是CPU資源分配和調(diào)度的獨(dú)立單位
2 .進(jìn)程分為三個(gè)部分:程序清蚀,數(shù)據(jù)集匕荸,進(jìn)程控制塊三部分
3 .進(jìn)程的局限是創(chuàng)建,撤銷和切換的開銷比較大

線程

1 .線程是進(jìn)程之后發(fā)展而來的概念枷邪,也叫輕量級(jí)進(jìn)程榛搔,是程序執(zhí)行中最小的執(zhí)行單元
2 .一個(gè)進(jìn)程可以包含多個(gè)線程,線程的有點(diǎn)事減小了程序并發(fā)執(zhí)行的開銷东揣,提高了操作系統(tǒng)的并發(fā)性能
3 .缺點(diǎn)是線程沒有自己的系統(tǒng)資源践惑,只有運(yùn)行時(shí)必不可少的資源,同一進(jìn)程的各個(gè)線程可以共享進(jìn)程所擁有的系統(tǒng)資源
4 .某些獨(dú)占性資源存在鎖機(jī)制嘶卧,處理不當(dāng)會(huì)產(chǎn)生死鎖

協(xié)程

1 .一種用戶態(tài)的輕量級(jí)線程尔觉,又叫微線程
2 .協(xié)程的調(diào)度完全由用戶控制。一旦完成任務(wù)芥吟,協(xié)程就會(huì)退出
3 .協(xié)程最大的有點(diǎn)事輕量級(jí)侦铜,可以創(chuàng)建上萬個(gè)而不會(huì)導(dǎo)致系統(tǒng)資源枯竭
4 .協(xié)程執(zhí)行效率高专甩,沒有線程切換的開銷。線程數(shù)量越多钉稍,協(xié)程的性能優(yōu)勢(shì)越明顯

G

1.表示goroutine,每個(gè)goroutine對(duì)應(yīng)一個(gè)G結(jié)構(gòu)體涤躲,g存儲(chǔ)goroutine的運(yùn)行棧,運(yùn)行狀態(tài)以及任務(wù)函數(shù)
2.可重用贡未。
3.g并非執(zhí)行體种樱,必須綁定到p上才能被調(diào)度執(zhí)行
4.g的眼里只有p,在g的眼里羞秤,p提供了g運(yùn)行的一切資源和環(huán)境缸托,p就是他的“CPU”

P

1.一個(gè)抽象的資源或者上下文左敌,表示一個(gè)邏輯處理器一個(gè)p綁定一個(gè)os線程
2.對(duì)于M來說瘾蛋,p提供相關(guān)的執(zhí)行環(huán)境,如內(nèi)存分配,任務(wù)隊(duì)列等
3.p的數(shù)量決定了系統(tǒng)最大可并行的G的數(shù)量矫限,p的數(shù)量是由GOMASXPROCS決定的哺哼,但是最大值為256

M

1.os線程抽象,代表真正可以執(zhí)行計(jì)算的資源叼风,在綁定有效的P后取董,進(jìn)入調(diào)度器循環(huán)
2.循環(huán)機(jī)制就是從全局隊(duì)列,p的本地隊(duì)列以及等待隊(duì)列中獲取G无宿,切換g的執(zhí)行棧上面執(zhí)行g(shù)的函數(shù)
3.調(diào)用goexit做清理工作并回到M,如此反復(fù)茵汰,m并不保留g的狀態(tài),這是g可以跨M調(diào)度
4.m數(shù)量是不固定的孽鸡,為了防止創(chuàng)建太多os線程導(dǎo)致調(diào)度不過來蹂午,最大顯示為10000

調(diào)度模型

https://user-gold-cdn.xitu.io/2018/6/11/163edf32b179eb4a?imageslim
1.go調(diào)度器工作時(shí)會(huì)維護(hù)兩種用來保存G的工作隊(duì)列,一個(gè)是全局隊(duì)列彬碱,一個(gè)是每個(gè)p的本地隊(duì)列
2.當(dāng)使用go關(guān)鍵字創(chuàng)建一個(gè)新的gogroutine時(shí)豆胸,他會(huì)優(yōu)先被放入本地的p隊(duì)列
3.為了運(yùn)行g(shù),m需要綁定一個(gè)p,接著m會(huì)啟動(dòng)一個(gè)os線程,循環(huán)從p的本地隊(duì)列里面取出一個(gè)g并且執(zhí)行巷疼。
4.當(dāng)m執(zhí)行完p的本地隊(duì)列中的所有g(shù)之后晚胡,p就會(huì)先去全局隊(duì)列找一下,如果沒有的話嚼沿,就去另外的一個(gè)p估盘,從他的隊(duì)列拿走一半的p到自己的隊(duì)列中去執(zhí)行
5.調(diào)度阻塞的情況
5.1.用戶態(tài)的阻塞

1.當(dāng)goroutine因?yàn)閏hannel操作或者net work i/o操作而阻塞的時(shí)候,對(duì)應(yīng)的G會(huì)被放到某個(gè)wait隊(duì)列中骡尽,改G的狀態(tài)由gruning變?yōu)間waiting遣妥,M會(huì)跳過這個(gè)g去執(zhí)行下一個(gè)g
2 .golang已經(jīng)用netpooler實(shí)現(xiàn)了goroutine網(wǎng)絡(luò)io阻塞,這個(gè)不會(huì)導(dǎo)致m被阻塞爆阶,僅僅會(huì)阻塞g
3 .當(dāng)阻塞的g被另一端的g2喚醒的時(shí)候燥透,如channel的可讀和寫通知沙咏,g被標(biāo)記為runable,嘗試加入g2所在的p的runnext,然后在世p的本地隊(duì)列 和全局隊(duì)列

5.2.系統(tǒng)調(diào)用阻塞

1 .當(dāng)g被阻塞到某個(gè)系統(tǒng)調(diào)用上時(shí)班套,g會(huì)阻塞在gsyscall狀態(tài)肢藐,m處于block on syscall狀態(tài),注意吱韭,此時(shí)的m可被搶占式調(diào)度的吆豹,執(zhí)行該G的m會(huì)與p解綁。p會(huì)嘗試與其他idle的m綁定理盆,繼續(xù)執(zhí)行剩余的g
2 .如果沒有其他運(yùn)行的m痘煤,但是p的本地隊(duì)列任然有g(shù)需要執(zhí)行,則新建一個(gè)M
3 .系統(tǒng)調(diào)用完成之后猿规,g會(huì)重新嘗試獲取一個(gè)運(yùn)行的p進(jìn)入他的本地隊(duì)列恢復(fù)執(zhí)行衷快,如果沒有g(shù)會(huì)被加上runable標(biāo)記,加入全局隊(duì)列
4 .搶占式調(diào)度的原理讓runtime有機(jī)會(huì)檢查是否需要執(zhí)行搶占調(diào)度姨俩。這種解決方案只能說局部解決了“餓死”問題蘸拔,對(duì)于沒有函數(shù)調(diào)用,純算法循環(huán)計(jì)算的G环葵,scheduler依然無法搶占
5 .如果此時(shí)沒有idle的M调窍,則會(huì)新創(chuàng)建一個(gè)M,這就是為何大量I/O操作導(dǎo)致大量Thread被創(chuàng)建的原因

5.3 .如果一個(gè)goroutine在某個(gè)操作上阻塞张遭,Go運(yùn)行時(shí)會(huì)調(diào)度另外一 個(gè)goroutine邓萨。即使成千上萬的Goroutine被創(chuàng)建了出來,如果它們阻塞在某個(gè)操作上菊卷,也不會(huì)浪費(fèi)系統(tǒng)資源缔恳。從操作系統(tǒng)的視角來看,你的程序的行為就像是一個(gè)事件驅(qū)動(dòng)的C程序似的
6 .將創(chuàng)建的goroutine按照一定的算法放到“CPU”上執(zhí)行的程序就稱為goroutine調(diào)度器或者goroutine scheduler
7 .一個(gè)go程序?qū)Σ僮飨到y(tǒng)來說只是一個(gè)用戶級(jí)程序的烁,對(duì)操作系統(tǒng)來說褐耳,并不知道goroutine的存在
8 .goroutine的調(diào)度全靠go自己完成,實(shí)現(xiàn)go程序內(nèi)goroutine之間公平的競(jìng)爭(zhēng)cpu資源
9 .將goroutines按照一定算法放到不同的操作系統(tǒng)線程中去執(zhí)行渴庆。這種在語言層面自帶調(diào)度器的铃芦,我們稱之為**原生支持[并發(fā)]
10 .

搶占式調(diào)度G的細(xì)節(jié)

1 .和操作系統(tǒng)按時(shí)間片調(diào)度線程不同,go沒有時(shí)間片的概念襟雷,如果某個(gè)p沒有被system call調(diào)用刃滓,沒有io操作,沒有阻塞在一個(gè)channel上面耸弄,m停下當(dāng)前g執(zhí)行下一個(gè)g的方式咧虎,也是搶占式調(diào)度
2 .除非無限循環(huán)或者死循環(huán),否則只要g調(diào)用函數(shù)计呈,go runtime就有搶占g的機(jī)會(huì)砰诵。
3 .go程序啟動(dòng)的時(shí)候征唬,runtime會(huì)啟動(dòng)一個(gè)名為system的m,執(zhí)行以下操作

1 .每隔20us-10ms啟動(dòng)一次
2 .釋放閑置唱過5分鐘的物理內(nèi)存
3 .如果超過2分鐘沒有垃圾回收茁彭。強(qiáng)制執(zhí)行
4 .將長時(shí)間未處理的netpoll結(jié)果添加到 任務(wù)隊(duì)列中
5 .向長時(shí)間運(yùn)行的g任務(wù)發(fā)出搶占式調(diào)度 10ms這么長的執(zhí)行時(shí)間
6 .收回因syscall長時(shí)間阻塞的p

M-G出現(xiàn)的問題

1 .單一全局互斥鎖和集中狀態(tài)存儲(chǔ)的存在導(dǎo)致所有的goroutine相關(guān)操作总寒,比如創(chuàng)建和重新調(diào)度,都需要上鎖
2 .goroutine傳遞問題理肺,m需要經(jīng)常在M之間傳遞可運(yùn)行的goroutine摄闸,這導(dǎo)致調(diào)度延遲增大以及額外的性能損耗
3 .每個(gè)M做內(nèi)存緩存,導(dǎo)致內(nèi)存占用過高妹萨,數(shù)據(jù)局部性較差
4 .由于syscall調(diào)用而形成的劇烈的worker thread阻塞和解除阻塞年枕,導(dǎo)致額外的性能損耗
5 .最后的調(diào)度實(shí)現(xiàn)

1 .每個(gè)P維護(hù)一個(gè)本地的G隊(duì)列
2 .當(dāng)一個(gè)G被創(chuàng)建出來,或者變?yōu)榭蓤?zhí)行狀態(tài)時(shí)乎完,就放到本地的p可執(zhí)行隊(duì)列中
3 .當(dāng)一個(gè)g在M里面執(zhí)行結(jié)束后熏兄,p會(huì)從隊(duì)列中把G取出,如果此時(shí)p的隊(duì)列為空囱怕,P也不會(huì)就這么在那躺尸啥都不干霍弹,它會(huì)先嘗試從Global隊(duì)列尋找G來執(zhí)行,如果Global隊(duì)列為空娃弓,它會(huì)隨機(jī)挑選另外一個(gè)P,從它的隊(duì)列里中拿走一半的G到自己的隊(duì)列中執(zhí)行
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末岛宦,一起剝皮案震驚了整個(gè)濱河市台丛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌砾肺,老刑警劉巖挽霉,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異变汪,居然都是意外死亡侠坎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門裙盾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來实胸,“玉大人,你說我怎么就攤上這事番官÷辏” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵徘熔,是天一觀的道長门躯。 經(jīng)常有香客問我,道長酷师,這世上最難降的妖魔是什么讶凉? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任染乌,我火速辦了婚禮,結(jié)果婚禮上懂讯,老公的妹妹穿的比我還像新娘慕匠。我一直安慰自己,他們只是感情好域醇,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布台谊。 她就那樣靜靜地躺著,像睡著了一般譬挚。 火紅的嫁衣襯著肌膚如雪锅铅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天减宣,我揣著相機(jī)與錄音盐须,去河邊找鬼。 笑死漆腌,一個(gè)胖子當(dāng)著我的面吹牛贼邓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播闷尿,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼塑径,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了填具?” 一聲冷哼從身側(cè)響起统舀,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎劳景,沒想到半個(gè)月后誉简,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盟广,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年你弦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了戳葵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片式散。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拯欧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出毛甲,到底是詐尸還是另有隱情年叮,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布玻募,位于F島的核電站只损,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜跃惫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一叮叹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爆存,春花似錦蛉顽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至闲勺,卻和暖如春曾棕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背菜循。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工翘地, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人癌幕。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓衙耕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親勺远。 傳聞我的和親對(duì)象是個(gè)殘疾皇子橙喘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 前言 隨著服務(wù)器硬件迭代升級(jí),配置也越來越高谚中。為充分利用服務(wù)器資源渴杆,并發(fā)編程也變的越來越重要。在開始之前宪塔,需要了解...
    云爬蟲技術(shù)研究筆記閱讀 3,829評(píng)論 0 7
  • 1、并發(fā)與并行 并行(parallel):指在同一時(shí)刻囊拜,有多條指令在多個(gè)處理器上同時(shí)執(zhí)行某筐。并發(fā)(concurren...
    lesline閱讀 9,558評(píng)論 0 2
  • 進(jìn)程時(shí)代 后來蜜托,現(xiàn)代化的計(jì)算機(jī)有了操作系統(tǒng)抄囚,每個(gè)程序都是一個(gè)進(jìn)程,但是操作系統(tǒng)在一段時(shí)間只能運(yùn)行一個(gè)進(jìn)程橄务,直到這個(gè)...
    大學(xué)渣PG閱讀 1,914評(píng)論 0 1
  • 我們的程序是如何被運(yùn)行的幔托? 學(xué)習(xí)過操作系統(tǒng)的人,應(yīng)該對(duì)進(jìn)程和線程的模型都是有所了解的。按照我的理解:「進(jìn)程」是操作...
    蔡欣圻閱讀 2,860評(píng)論 1 7
  • 前言 隨著服務(wù)器硬件迭代升級(jí)重挑,配置也越來越高嗓化。為充分利用服務(wù)器資源,并發(fā)編程也變的越來越重要谬哀。在開始之前刺覆,需要了解...
    蔡欣圻閱讀 2,120評(píng)論 0 4