Golang調(diào)度器

本文盡量通俗易懂地講Go調(diào)度器(scheduler)的相關(guān)知識奴饮,尤其是普通開發(fā)者能夠關(guān)注和控制的部分纬向。調(diào)度器本身十分復(fù)雜择浊,所以下文難免有疏漏戴卜,發(fā)現(xiàn)后會盡量及時更新。

要點

  1. go程序的運(yùn)行琢岩,以goroutine為單位投剥,而goroutine實際運(yùn)行在某個系統(tǒng)線程內(nèi)。goroutine(可以非常多)和系統(tǒng)線程(相對比較少)并非一一對應(yīng)担孔。調(diào)度時江锨,既有os調(diào)度線程,也有g(shù)o調(diào)度器本身調(diào)度goroutine糕篇。簡言之啄育,go原生支持并發(fā),go調(diào)度器負(fù)責(zé)將各個goroutine調(diào)度到不同的操作系統(tǒng)線程中取執(zhí)行拌消。
  2. 三個定義:
    • G: goroutine挑豌,就是平常提到的go中的協(xié)程
    • P: process,處理器墩崩,有的文章說代表上下文氓英,也可以理解為附帶有上下文信息的令牌
    • M: machine,線程鹦筹,就是平常提到的操作系統(tǒng)中的線程
  3. Go早期是GM模型铝阐,后來因為性能問題轉(zhuǎn)而使用GPM模型
  4. 執(zhí)行機(jī)制:
    • M綁定P,才可以不斷去運(yùn)行(不同的可執(zhí)行的)G铐拐,可搶占式調(diào)度(靠sysmon)
    • P有自己的G隊列(無鎖訪問徘键,快);同時遍蟋,程序也有一個全局的G隊列
    • M執(zhí)行一些系統(tǒng)調(diào)用的時候吹害,可能會與P解除綁定;M也可能休眠
    • M, P, G 三者數(shù)量各異匿值,M默認(rèn)10000(SetMaxThreads更改赠制,一般不用),P默認(rèn)是機(jī)器CPU核數(shù)(可由GOMAXPROCS指定)挟憔,G沒有明確限制(通過go指令創(chuàng)建)钟些。

細(xì)節(jié)

  1. GM到GPM
    早期,GM模型有諸多問題绊谭,例如全局鎖政恍,M緩存內(nèi)存占用浪費(fèi)等,詳見《Scalable Go Scheduler Design》达传。因此篙耗,大神操刀加了一層中間層(P)迫筑,調(diào)度模型變成GPM,沿用至今(盜圖一張):

    GPM調(diào)度模型

    通俗地講宗弯,G要運(yùn)行脯燃,需要綁定一個P(放在P的本地隊列里),然后由與P綁定的操作系統(tǒng)線程M真正執(zhí)行蒙保。
    G切換時辕棚,只是M從G1切到G2而已,都是在用戶態(tài)進(jìn)行著邓厕,非常輕量逝嚎,不像操作系統(tǒng)切換M時比較重。
    P的本地隊列中缺少G時详恼,會從其他P的隊列里“偷”一些或者從全局隊列里取补君。
    借助于netpoller,發(fā)起網(wǎng)絡(luò)調(diào)用時昧互,G阻塞挽铁,M不阻塞,切換G即可硅堆。而發(fā)起文件IO等操作時屿储,會執(zhí)行(阻塞的)系統(tǒng)調(diào)用,(注:現(xiàn)在應(yīng)該實現(xiàn)了部分poller for os package)渐逃,此時M也會等待系統(tǒng)調(diào)用的返回够掠。M和G一起,會解除與P的綁定茄菊。如果P的本地隊列還有其他G疯潭,就會綁定另外一個空閑的M,如果沒有面殖,則新建一個M竖哩,然后繼續(xù)執(zhí)行可以執(zhí)行的G。

  2. 調(diào)度器實現(xiàn)了搶占
    也就是說如果一個G執(zhí)行太久脊僚,是會被切換出去的相叁。
    這樣可以確保整個程序看起來是“并發(fā)”執(zhí)行的,而不是一個G可以執(zhí)行時就是一直執(zhí)行辽幌,其他G都餓死增淹。
    但是切換點需要是函數(shù)調(diào)用。假設(shè)G中是不調(diào)函數(shù)的純無限循環(huán)計算乌企,還是無法被搶占虑润。

  3. 什么時候G會被調(diào)度

  • 被sysmon設(shè)置為搶占
  • channel阻塞或網(wǎng)絡(luò)IO
  • mutex等同步導(dǎo)致阻塞
  • 使用go關(guān)鍵字創(chuàng)建goroutine
  • GC過程中各種策略導(dǎo)致的調(diào)度
    runtime中,網(wǎng)絡(luò)IO的實現(xiàn)采用了kqueue (MacOS), epoll (Linux)或iocp (Windows) 加酵。
  1. 查看各種調(diào)度狀態(tài)
    執(zhí)行命令的時候拳喻,設(shè)置GODEBUG環(huán)境變量哭当。例如:GODEBUG=schedtrace=1000,scheddetail=1 godoc -http=:6060

  2. P有l(wèi)ocal隊列的好處
    其實好處有好幾點。比較明顯的是冗澈,GM模型里面钦勘,M切換G時,需要從全局隊列里面取渗柿,需要加鎖个盆。GPM中,M綁定著P朵栖,M切換的G都在P的本地G隊列中,不需要鎖柴梆。

  3. P默認(rèn)是機(jī)器邏輯核數(shù)
    因為超線程技術(shù)的存在陨溅,邏輯核數(shù)會與物理核數(shù)不同。下面的語句可以打印出邏輯核數(shù)绍在,通過GOMAXPROCS設(shè)置時门扇,可別弄錯了

fmt.Println(runtime.NumCPU())
  1. M默認(rèn)是10000
    M對應(yīng)的是sched.maxmcount,默認(rèn)10000偿渡。通過SetMaxThreads可修改臼寄,如果程序使用超過這個數(shù),會自動crash溜宽!
// 改動時也會檢查吉拳,并不能隨意設(shè)置值
if in > 0x7fffffff { // MaxInt32
    sched.maxmcount = 0x7fffffff
} else {
    sched.maxmcount = int32(in)
}
  1. 相關(guān)代碼片段(不詳細(xì)研究的可以不用看了)
    參見下一篇吧,這篇已很長了适揉。

參考鏈接:

  1. https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part2.html
  2. https://tonybai.com/2017/06/23/an-intro-about-goroutine-scheduler/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末留攒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子嫉嘀,更是在濱河造成了極大的恐慌炼邀,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剪侮,死亡現(xiàn)場離奇詭異拭宁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瓣俯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門杰标,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人降铸,你說我怎么就攤上這事在旱。” “怎么了推掸?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵桶蝎,是天一觀的道長驻仅。 經(jīng)常有香客問我,道長登渣,這世上最難降的妖魔是什么噪服? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮胜茧,結(jié)果婚禮上粘优,老公的妹妹穿的比我還像新娘。我一直安慰自己呻顽,他們只是感情好雹顺,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著廊遍,像睡著了一般嬉愧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上喉前,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天没酣,我揣著相機(jī)與錄音,去河邊找鬼卵迂。 笑死裕便,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的见咒。 我是一名探鬼主播偿衰,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼论颅!你這毒婦竟也來了哎垦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤恃疯,失蹤者是張志新(化名)和其女友劉穎漏设,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體今妄,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡郑口,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了盾鳞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片犬性。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖腾仅,靈堂內(nèi)的尸體忽然破棺而出乒裆,到底是詐尸還是另有隱情,我是刑警寧澤推励,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布鹤耍,位于F島的核電站肉迫,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏稿黄。R本人自食惡果不足惜喊衫,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杆怕。 院中可真熱鬧族购,春花似錦、人聲如沸陵珍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撑教。三九已至朝墩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伟姐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工亿卤, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留愤兵,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓排吴,卻偏偏與公主長得像秆乳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子钻哩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353