單程序時代的問題
多程序、多執行緒的問題
協程的問題m:goroutine協程
n:thread執行緒
m想要執行、放回g都必須訪問全域性g佇列,並且m有多個,即多執行緒訪問同一資源需要加鎖進行保證互斥/同步,所以全域性g佇列是有互斥鎖進行保護的。
問題:
建立、銷毀、排程g都需要每個m獲取鎖,這就形成了激烈的鎖競爭
m轉移g會造成延遲和額外的系統負載
系統呼叫(cpu在m之間的切換)導致頻繁的執行緒阻塞和取消阻塞操作增加了系統開銷
全域性佇列(global queue):存放等待執行的g
p的本地佇列:同全域性佇列類似,存放的也是等待執行的g,存的數量有限,不超過256個。新建g'時,g'優先加入到p的本地佇列,如果佇列滿了,則會把本地佇列中一半的g移動到全域性佇列
p列表:所有的p都在程式啟動時建立,並儲存在陣列中,最多有gomaxprocs
(可配置)個
m:執行緒想執行任務就得獲取p,從p的本地佇列獲取g,p隊列為空時,m也會嘗試從全域性佇列拿一批g放到p的本地佇列,或從其他p的本地佇列偷一半放到自己p的本地佇列。m執行g,g執行之後,m會從p獲取下乙個g,不斷重複下去
p和m何時會被建立?
參考:
Golang排程器GMP模型
g goroutine 我們所說的協程,為使用者級的輕量級執行緒,每個goroutine物件中的sched儲存著其上下文資訊.go1.11版本預設stack大小為2kb stackmin 2048 建立乙個g物件,然後放到g佇列 等待被執行 func newproc1 fn funcval,argp...
Golang排程器GMP學習筆記(二)
我們通過 go func 來建立乙個goroutine 有兩個儲存g的佇列,乙個是區域性排程器p的本地佇列 乙個是全域性g佇列。新建立的g會先儲存在p的本地佇列中,如果p的本地佇列已經滿了就會儲存在全域性的佇列中 g只能執行在m中,乙個m必須持有乙個p,m與p是1 1的關係。m會從p的本地佇列彈出乙...
深入理解Golang排程器GMP模型
隨著伺服器硬體的公升級,配置越來越高,為了充分利用伺服器資源,併發變成也就變得越來越重要。併發 邏輯上具有處理多個同時任務的能力。並行 物理上同一時刻執行多個併發任務。通常所說的併發程式設計,也就是說它允許多個任務同時執行,但實際上並不一定在同一時刻被執行。在單核處理器上,通過多執行緒共享cpu時間...