微信搜索【 腦子進煎魚了】關注這一隻爆肝煎魚。本文 GitHub github.com/eddycjy/blog 已收錄,有個人系列文章、資料和開源 Go 圖書。
你們好,我是煎魚。git
最近金三銀四,是面試的季節。在個人 Go 讀者交流羣裏出現了許多小夥伴在討論本身面試過程當中所遇到的一些 Go 面試題。github
今天的主角,是 Go 面試的萬能題 GMP 模型的延伸題(疑問),那就是 」GMP 模型,爲何要有 P?「golang
進一步推敲問題的背後,其實這個面試題本質是想問:」GMP 模型,爲何不是 G 和 M 直接綁定就完了,還要搞多一個 P 出來,那麼麻煩,爲的是什麼,是要解決什麼問題嗎?「面試
這篇文章煎魚就帶你一同探索,GM、GMP 模型的變遷是由於什麼緣由。算法
在 Go1.1 以前 Go 的調度模型其實就是 GM 模型,也就是沒有 P。緩存
今天帶你們一塊兒回顧過去的設計。服務器
咱們瞭解一個東西的辦法之一就是看源碼,和煎魚一塊兒看看 Go1.0.1 的調度器源碼的核心關鍵步驟:微信
static void schedule(G *gp) { ... schedlock(); if(gp != nil) { ... switch(gp->status){ case Grunnable: case Gdead: // Shouldn't have been running! runtime·throw("bad gp->status in sched"); case Grunning: gp->status = Grunnable; gput(gp); break; } gp = nextgandunlock(); gp->readyonstop = 0; gp->status = Grunning; m->curg = gp; gp->m = m; ... runtime·gogo(&gp->sched, 0); }
schedlock
方法來獲取全局鎖。gput
方法來保存當前 Goroutine 的運行狀態等信息,以便於後續的使用;nextgandunlock
方法來尋找下一個可運行 Goroutine,而且釋放全局鎖給其餘調度使用。runtime·gogo
方法,將剛剛所獲取到的下一個待執行的 Goroutine 運行起來。經過對 Go1.0.1 的調度器源碼剖析,咱們能夠發現一個比較有趣的點。那就是調度器自己(schedule 方法),在正常流程下,是不會返回的,也就是不會結束主流程。網絡
他會不斷地運行調度流程,GoroutineA 完成了,就開始尋找 GoroutineB,尋找到 B 了,就把已經完成的 A 的調度權交給 B,讓 GoroutineB 開始被調度,也就是運行。併發
固然了,也有被正在阻塞(Blocked)的 G。假設 G 正在作一些系統、網絡調用,那麼就會致使 G 停滯。這時候 M(系統線程)就會被會從新放內核隊列中,等待新的一輪喚醒。
這麼表面的看起來,GM 模型彷佛牢不可破,毫完好陷。但爲何要改呢?
在 2012 年時 Dmitry Vyukov 發表了文章《Scalable Go Scheduler Design Doc》,目前也依然成爲各大研究 Go 調度器文章的主要對象,其在文章內講述了總體的緣由和考慮,下述內容將引用該文章。
當前(代指 Go1.0 的 GM 模型)的 Goroutine 調度器限制了用 Go 編寫的併發程序的可擴展性,尤爲是高吞吐量服務器和並行計算程序。
實現有以下的問題:
存在單一的全局 mutex(Sched.Lock)和集中狀態管理:
Goroutine 傳遞的問題:
每一個 M 都須要作內存緩存(M.mcache):
頻繁的線程阻塞/解阻塞:
爲了解決 GM 模型的以上諸多問題,在 Go1.1 時,Dmitry Vyukov 在 GM 模型的基礎上,新增了一個 P(Processor)組件。而且實現了 Work Stealing 算法來解決一些新產生的問題。
GMP 模型,在上一篇文章《Go 羣友提問:Goroutine 數量控制在多少合適,會影響 GC 和調度?》中已經講解過了。
以爲不錯的小夥伴能夠關注一下,這裏就再也不復述了。
加了 P 以後會帶來什麼改變呢?咱們再更顯式的講一下。
這時候就有小夥伴會疑惑了,若是是想實現本地隊列、Work Stealing 算法,那爲何不直接在 M 上加呢,M 也照樣能夠實現相似的組件。爲何又再加多一個 P 組件?
結合 M(系統線程) 的定位來看,若這麼作,有如下問題:
所以使用 M 是不合理的,那麼引入新的組件 P,把本地隊列關聯到 P 上,就能很好的解決這個問題。
今天這篇文章結合了整個 Go 語言調度器的一些歷史狀況、緣由分析以及解決方案說明。
」GMP 模型,爲何要有 P「 這個問題就像是一道系統設計瞭解,由於如今不少人爲了應對面試,會硬背 GMP 模型,或者是泡麪式過了一遍。而理解其中真正背後的緣由,纔是咱們要去學的要去理解。
知其然知其因此然,纔可破局。
如有任何疑問歡迎評論區反饋和交流,最好的關係是互相成就,各位的點贊就是煎魚創做的最大動力,感謝支持。
文章持續更新,能夠微信搜【腦子進煎魚了】閱讀,回覆【 000】有我準備的一線大廠面試算法題解和資料;本文 GitHub github.com/eddycjy/blog 已收錄,歡迎 Star 催更。