一架梯子,一头程序猿,仰望星空!
Golang高级特性面试题 > 内容正文

能简单介绍下GO的GMP 模型吗?


问题简答

Go协程调度器采用的是GMP模型,描述如何给千上万个Goroutine分配CPU资源,让他们执行任务。

问题详解:

Golang的一大特色就是Goroutine。Goroutine是Golang支持高并发的重要保障。Golang可以创建成千上万个Goroutine来处理任务,将这些Goroutine分配、负载、调度到处理器上采用的是G-M-P模型。

GMP模型概念

GMP三个字母含义如下:

  • G:Goroutine,也就是 go 里的协程,是用户态的轻量级线程,具体可以创建多个 goroutine ,取决你的内存有多大。

  • M:Thread,也就是操作系统线程,go runtime 最多允许创建 10000 个操作系统线程,超过了就会抛出异常

  • P:Processor,处理器,数量默认等于开机器的cpu核心数,若想调小,可以通过 GOMAXPROCS 这个环境变量设置。

GMP队列

在整个 Go 调度器的生命周期中,存在着两个非常重要的队列:

  • 全局队列(Global Queue):全局只有一个
  • 本地队列(Local Queue):每个 P 都会维护一个本地队列

GMP调度过程

GMP调度流程大致如下:

  1. 线程M想运行任务就需得获取 P,即与P关联。
  2. 然从 P 的本地队列(LRQ)获取 G
  3. 若LRQ中没有可运行的G,M 会尝试从全局队列(GRQ)拿一批G放到P的本地队列,
  4. 若全局队列也未找到可运行的G时候,M会随机从其他 P 的本地队列偷一半放到自己 P 的本地队列。
  5. 拿到可运行的G之后,M 运行 G,G 执行之后,M 会从 P 获取下一个 G,不断重复下去。