GMP 是 Go 运行时并发调度的三元模型,分别对应 G(Goroutine)、M(OS线程)、P(逻辑处理器),三者互相约束、协同完成用户态协程调度,完全脱离操作系统内核调度器干预。上方三元绑定图已完整呈现三者的结构体定义与绑定关系。
G:Goroutine 状态流转机
G 代表用户创建的协程,存储独立执行栈、程序计数器PC、状态标记、上下文、等待事件,Go 1.22 优化栈扩容/缩容阈值,减少栈内存抖动。G 的核心状态流转如下:
M:操作系统内核线程
M 是操作系统提供的真实内核线程,承载G的执行上下文,M不具备调度能力,必须绑定P才能执行用户G代码;执行纯系统调用时可临时解绑P。M 分为两类:工作M(绑定P,执行业务G)与系统M(G进入阻塞syscall时创建,专门处理阻塞IO,不占用P)。
P:逻辑处理器,调度核心中介
P 是 GMP 模型最关键的设计,作为 M 与 G 的中间调度层,限定单 CPU 核心并发执行数量(数量等于 GOMAXPROCS),持有本地 G 就绪队列、缓存调度上下文,隔离内核线程与用户协程。Go 1.22 将本地 runq 队列扩容至 256,减少频繁落全局队列带来的全局锁争抢。
控制并发上限P 总数 = CPU 核心数,避免内核线程无限制创建;本地任务队列减少全局队列锁竞争,Go 1.22 优化无锁入队逻辑;任务窃取载体多核 P 之间平衡 G 执行负载;内存缓存mcache 分配器,降低堆内存分配锁开销。
G-M-P 基础绑定关系
- 同一时刻一个 P 只能绑定一个 M,一个 M 仅持有一个 P
- 一个 M 同一时间只能执行一个 G
- 一个 G 运行时仅绑定一组 M+P阻塞时 G 脱离 M/P,M 可解绑 P