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的作用是什么?/
作者
Darven
发布于
2025年12月9日
许可协议