Golang GPM模型

Golang GPM模型浅析

概览

概览图

GPM 分别代表

  • G: Goroutine, Go协程,是参与调度与执行的最小单元。
  • P: P, Processor,指的是逻辑处理器,P关联了本地可运行的G队列,最多可存放256个G。P的数量最多是GOMAXPROCS(可配置)个。
  • M: M, Machine,指的是系统级线程,Go程序启动时会设置M的最大数量,默认为10000,但是内核很难支持这么多的线程,所以这个限制可以hulue。

调度器的生命周期

m0

M0是启动程序后的编号为0的主线程,这个M对应的实例会在全局变量runtime.m0中,不需要在Heap上分配,M0负责执行初始化操作和启动第一个G,在之后M0就和其他的 M 一样了。

G0

G0是每次启动一个 M都会第一个创建的 goroutine,G0仅用于负责调度的 GG0不指向任何可执行的函数,每个M都会有一个自己的G0,在调度或者系统调用时会使用G0的栈空间,全局变量的G0M0G0

1
2
3
4
5
6
package main

import "fmt"
func main() {
  fmt.Println("Hello World!")
}

以上代码所示,分析一下执行过程

  • runtime 创建最初的线程 m0 和 goroutine g0,并把二者关联。
  • 调度器初始化:初始化 m0、栈、垃圾回收,以及创建和初始化由 GOMAXPROCSP 构成的 P 列表。
  • 示例代码中的 main 函数是 main.mainruntime中也有一个main函数 - runtime.main,代码经过编译后,runtime.main会调用 main.main,程序启动时会为 runtime.main创建goroutine,称它为 main goroutine。然后把 main goroutine 加入到 P 的本地队列中。
  • 启动m0m0已经绑定了P,会从P的本地队列获取G,然后获取到 main goroutine
  • G 拥有栈, M 根据 G 中的栈信息和调度信息设置运行环境。
  • M 运行 G
  • G退出,再次回到M获取可运行的G,这样重复下去,直到main.main退出,runtime.main 执行 Defer 和 Panic 处理,或调用 runtime.exit 退出程序。
皖ICP备20014602号
Built with Hugo
Theme Stack designed by Jimmy