淺析Go中的MPG模式(一)

Goroutine(協程)
首先了解一下協程(goroutine)這個東西
一、Go線程(主線程,通常稱爲線程,有的大佬們也直接叫進程),也可理解爲進程。是一個物理級線程,重量級的,很是耗費CPU資源網絡


二、一個線程上能夠有多個協程(goroutine),協程是輕量級的線程(go對於線程進行的特殊處理)。邏輯態,消耗資源相對少。按照消耗資源能夠這樣排序:進程 >= 主線程 > 子線程 >= 協程併發


三、Go協程特色
(1)有獨立的棧空間
(2)共享程序堆空間
(3)調度由用戶(程序)控制
(4)協程是輕量級的線程ide


四、主線程退出了,協程即便未執行完畢也會中止,退出程序。操作系統


MPG模式:

一、解釋一下MPG含義:
M(Machine):操做系統的主線程
P(Processor):協程執行須要的資源(上下文context),能夠看做一個局部的調度器,使go代碼在一個線程上跑,他是實現從N:1到N:M映射的關鍵
G(Gorountine):協程,有本身的棧。包含指令指針(instruction pointer)和其它信息(正在等待的channel等等),用於調度。一個P下面能夠有多個G線程


二、**P的數量能夠經過GOMAXPROCS()來設置,**他其實表明了真正的併發度,即有多少個goroutine能夠同時運行。P同時也維護着G(協程)的隊列(稱之爲runqueue進程隊列)。Go代碼中的M每有一個語句被執行,P就在末尾加入一個G(從runqueue隊列中取出來的),在下一個調度點(P),就從runqueue隊列中取出G。(圖片來源於網絡,太多相似的忘了在哪截的)
在這裏插入圖片描述指針


三、P能夠在OS線程(主線程,或者是M)被阻塞時,轉到另外一個OS線程(M)!Go中的調度器保證有足夠的線程來運行全部的P。當啓用一個M0中的G0被sysCall(系統調用)的時候,M0下面的P轉給另外一個線程M1(能夠是建立的,也能夠是本來就存在的)。M1接受了P(包括P所帶的runqueue的隊列裏面全部狀態的G,但不包括已經被syscall的G0),繼續運行。而M0會等待執行syscall的G0的返回值。當G0的syscall結束後,他的主線程M0會嘗試取得一個P來運行G0,通常狀況下,他會從其餘的M裏面偷一個P過來,若是沒有偷到的話就會把G0放到一個Global runqueue(全局進程隊列)中,而後把本身(M0)放進線程池或者轉爲休眠狀態。協程


四、Global runqueue是各個P在運行完本身的本地的goroutine runqueue後用來拉取新goroutine的地方。P也會週期性的檢查這個Global runqueue上的goroutine,不然全局runqueue上的goroutine可能得不到執行而餓死。。。
九、當P中的runqueue隊列裏面的G所有執行完畢以後,他會偷取未執行完的P中的G(偷取一半)!blog

相關文章
相關標籤/搜索