Golang中的GMP调度模型是如何工作的?P的作用是什么?
什么是GMP模型?
G: golang协程,用户级线程,在用户态调度
- 初始栈小,2kb,支持动态扩容,可以达到GB级别
- 在用户态调度,上下文开销小
- 结构体包括:栈指针,程序计数器,状态,绑定的M和P,阻塞原因
M: 内核级线程,真正调度执行的单位
- 默认最大数量是10000,可以动态创建和销毁
- M必须绑定P才能执行G(没有G的话就会进入休眠池)
- 如果G执行阻塞操作,除了网络IO,基本都会M解绑P
P: 逻辑处理器
- 数量是GOMAXPROCS控制,默认是CPU核心数
- 持有运行时核心资源,独立内存分配缓存
- 本地队列默认是256个,无锁访问,全局需要加锁
GMP怎么工作的?
1. 调度初始化
程序启动,RUNTIME初始化
- P池,全局队列,空闲M池
- 将main封装成main goroutine放入某个本地队列
2. M获得G的优先级
- M绑定P之后,优先消费P本地队列的G(FIFO)
- 本地队列为空时候,先从全局队列批量取出G到本地队列
- 全局为空的话,触发工作窃取,去别的P里面窃取后半部分的G
3. G阻塞
- 一旦G和M阻塞,就会将M和P解绑,然后P寻找空闲M,如果没有就会创建一个M进行绑定,然后新M消费P的G
- 如果G解除阻塞,会被放到全局队列获得本地队列,等待调度
- 原来的M如果没有P绑定就会进入空闲池.
P的作用?
1. 并行度的核心控制器
P的数量等于CPU核心数量,也就是说支持同时执行的G的数量
2. 性能优化
- 本地队列无锁,避免了锁竞争带来的开销
- 独立资源
3. 调度的桥梁角色
P连接M和G,M必须绑定P才能执行
Golang中的GMP调度模型是如何工作的?P的作用是什么?
https://darven-cs.github.io/2025/12/09/Golang中的GMP调度模型是如何工作的?P的作用是什么?/