总述

img

GMP 模型

  • G(Goroutine):表示一个 Goroutine,包含栈和相关上下文信息。
  • M(Machine):表示一个执行线程,负责将 Goroutine 映射到操作系统的线程上。每个 M 都有自己的调用栈和寄存器状态。(数量是动态的,由调度器决定,根据当前负载动态变化,默认为 10000
  • P(Processor):表示一个逻辑处理器,维护一个处于可运行状态的Goroutine 队列,每个 M 都和一个 P 有关。(数量是固定的

特点

  1. 抢占式协调:在协程中需要一个协程主动让出 CPU 下一个协程才能使用 CPU, 而 Goroutine 规定一个 Goroutine 每次最多只能占用 10ms 的 CPU,然后就要切换到下一个, 防止其他协程长时间不被执行。
  2. 复用线程:Go 语言的调度器会复用线程,而不是每次都创建新的线程,这样可以减少线程创建和销毁的开销,提高性能。
  3. 工作偷取(Work stealing):当 M 没有可运行的 G 时,会尝试从其他线程绑定的 P 的本地队列中偷取一半的 G来运行,而不是销毁 M
  4. 挂起机制(Hand off):当 G 由于系统调用而阻塞时, M 会释放绑定的 P 供其他 M 使用
  5. 并行:通过 GOMAXPROCS 配置 P 的数量,从而实现并行执行,P 的数量决定了并行度,P 的数量等于 CPU 核数时,可以实现最大并行度。

结构

全局队列:是存放所有正在等待的 G。
本地队列:存放当前 P 的 G,每个 P 都有一个队列,用于存放当前的 P 等待和正在运行的 G,最大数量为 256 个

二者之间的关系(偷取机制

  1. 只有本地队列满了,才会存放在全局队列中
  2. 如果一个本地队列为空,那么他会从其他的本地队列获取一半到自己的本地队列中。
    img