零聲golang云?生原?Go語(yǔ)言 分布式 微服務(wù) DevOps k8s二次開(kāi)發(fā)
golang 的 GPM 模型
為了實(shí)現(xiàn) golang 的調(diào)度,golang 抽象出了三個(gè)結(jié)構(gòu),也就是我們常見(jiàn)的?G、P、M。
G:也就是協(xié)程 goroutine,由 Go runtime 管理。我們可以認(rèn)為它是用戶級(jí)別的線程。
goroutine 非常的輕量,初始分配只有 2KB,當(dāng)??臻g不夠用時(shí),會(huì)自動(dòng)擴(kuò)容。同時(shí),自身存儲(chǔ)了執(zhí)行 stack 信息、goroutine 狀態(tài)以及 goroutine 的任務(wù)函數(shù)等。
P:processor 處理器。P 的數(shù)量默認(rèn)跟 CPU 的核心數(shù)一樣,如果是多核的 CPU,則會(huì)有多個(gè) P 會(huì)被創(chuàng)建。
每當(dāng)有 goroutine 要?jiǎng)?chuàng)建時(shí),會(huì)被添加到 P 上的 goroutine?本地隊(duì)列上,如果 P 的本地隊(duì)列已滿,則會(huì)維護(hù)到全局隊(duì)列里。
在進(jìn)行調(diào)度時(shí),會(huì)優(yōu)先從本地隊(duì)列獲取 goroutine 來(lái)執(zhí)行。
如果本地隊(duì)列沒(méi)有,會(huì)從其他的 P 上偷取?goroutine。
如果其他 P 上也沒(méi)有,則會(huì)從全局隊(duì)列上獲取 goroutine。
這樣通過(guò)上面的策略,就能盡最大努力保證有 goroutine 可運(yùn)行。
M:系統(tǒng)線程。在 M 上有調(diào)度函數(shù),它是真正的調(diào)度執(zhí)行者,M 需要跟 P 綁定,并且會(huì)讓 P 按上面的原則挑出個(gè) goroutine 來(lái)執(zhí)行。
M 雖然從 P 上挑選了 G 執(zhí)行,但 M 并不保存 G 的上下文信息,而是 G 自
己保存了相關(guān)信息,這樣有利于轉(zhuǎn)移到其他 M 上,在不同的 M 上運(yùn)行。
