Go 語言并發模型:MPG
Go 的并發模型主要由三個部分構成:
-
M (Machine)
系統線程,用于實際執行任務。 -
P (Processor)
邏輯處理器,負責管理和調度 goroutine。每個 P 擁有一個本地隊列和關聯的全局 G 隊列。 -
G (Goroutine)
Go 語言中的協程,是程序執行的基本單元。
M 與 P 的關系
-
1:1 關系
每個運行的任務對應的 M 必須關聯一個 P,即 M 和 P 是一對一的關系。 -
本地隊列與全局隊列
- 每個 P 擁有自己的本地 G 隊列,當本地隊列滿時,多余的 G 會被放入全局隊列中。
系統調用和調度機制
Syscall 與阻塞處理
-
線程阻塞
- 當某個 M(例如 M0)在執行 syscall 時陷入阻塞,它會釋放所綁定的 P。
- 該 P 會轉交給一個空閑的 M(例如 M1)繼續執行。
- 如果沒有空閑的 M,則會創建新的 M 來接管 P。
-
系統調用結束后的處理
- 如果 M0 在系統調用結束后能獲取到空閑的 P,則繼續執行原來的 G(例如 G0)。
- 如果沒有空閑的 P,則 G0 會被放入全局隊列,等待其它 P 調度,而 M0 則進入緩存池等待喚醒。
- 全局隊列 (runqueue)
該隊列用于調度各個 P 在運行完本地隊列后的 G。
Work Stealing 機制
- 調度策略
- 當當前線程的本地隊列中沒有可運行的 G 時,會首先嘗試從全局隊列中獲取任務。
- 如果全局隊列中也沒有可用的 G,該線程將從其它線程綁定的 P 中“偷取”一半的 G 以保證負載均衡。
Sysmon 協程
-
作用
- sysmon 協程專門用于監控和管理協程狀態,不需要 P 的支持即可執行。
-
搶占策略
- 在 Go 中,所有 goroutine 最多占用 CPU 時間為 10ms,超過這個時間的協程會被搶占,以防止某個 goroutine 獨占 CPU,確保其他 goroutine 得到運行機會。
補充機制
-
協程搶占
- 通過協程搶占機制,Go 能夠在長時間運行的協程中及時切換,確保系統中各個任務的公平調度。
-
垃圾回收
- Go 的垃圾回收機制會定期回收不再使用的內存,優化內存資源的利用。