1291 words
6 minutes
线程模型与GMP调度模型

线程调度模型#

有三大线程调度模型,其主要差异在于用户级线程(即协程)与KSE(Kernel Scheduling Entity 内核调度实体)之间的对应关系

内核级线程模型#

用户级线程与内核级线程1:1对应,线程创建,切换,销毁均需内核参与
优点

  • 多处理器环境中,内核能并行执行同一进程的多个线程
  • 同一进程中的某个线程阻塞不会导致进程被阻塞,可以继续执行同进程下别的线程
  • 内核在某进程的线程阻塞时可切换执行另一进程的线程

缺点

  • 线程创建,切换,销毁成本高

用户级线程模型#

用户级线程与内核级线程N:1对应,线程创建,切换,销毁等操作均在用户态完成(内核无法感知)
优点

  • 线程创建,切换,销毁等管理代价相比前者小得多
  • 线程能利用的表空间和堆栈空间相比前者更多[相较前者更自由,不受内核固定栈大小限制(内核线程一般固定 8MB)]且可动态增长

缺点

  • 进程同一时间只能有一个线程运行(因为内核无法感知,并不清楚有多线程存在),单一线程阻塞会导致整个进程阻塞
  • 多处理机情况下,进程也只能在单个处理机下时分复用(只对应1个KSE,退化为按进程分配时间片)

两级线程模型#

用户级线程与内核级线程N对应,线程创建,调度在用户态完成,多个用户级线程被绑定到一个或多个内核级线程上
该模型充分吸收前两者模型的优点,并尽量避免缺点,实现较为复杂

GMP(Goroutine-Machine-Processor)#

首先明确,内核不会自行将线程置于某种状态,内核只会根据程序发起的系统调用将线程置于对应状态,并且给处于runnable状态的线程分配CPU时间片

G即Goroutine,Go语言的轻量级线程,属于两级线程模型
M实际上即系统线程,与KSE(Kernel Scheduling Entity 内核调度实体)一一对应

KSE 是可被操作系统内核调度的对象实体,是最小调度单元

P即Processor,指逻辑处理器(即资源,但不等同于CPU逻辑核心,为runtime调度资源),其内部关联了本地G队列(LRQ),最多可存放256个G

GMP相互关系为:G在P中排队等待执行,M需要先持有P才能被分配CPU时间片实际运行

此处不讨论G0(G0属于M,是特殊的Goroutine)

GMP调度流程大致为:#

  • M抢得(持有)一个P
  • M从P的本地队列(LRQ)中得到一个等待被执行的G
    • 若P中无待执行的G,则从全局G队列中取得一批G放入LRQ中
    • 若全局队列中也无待执行G,M进入sleep
  • M得到CPU时间片,开始执行G
    • 若执行时遇到阻塞
      • 若为syscall阻塞,M进入阻塞状态,解除与P的关联,G阻塞结束重新进入某个P中等待执行,M阻塞结束后重新抢夺P后继续下一步
      • 若为netpoller等异步挂起(用户态阻塞)状态,G被放入netpoll阻塞表等待回调,M不阻塞,继续下一步
  • G执行完毕,M重新获取LRQ中的下一个G,重复以上操作

特殊情况:#

M0,即启动程序后创建的编号0的主线程,M0上的实例放置在全局变量(runtime.m0)中,不在heap上分配,M0特殊仅因为其执行了启动和初始化流程,以上流程结束后M0与其他普通M等价,并没有特权

但M0仍具有特殊性,即永不销毁(除非程序结束运行),通常也承担绑定 signal-handling thread(处理同步信号)

G0,即每启动一个M会自动创建的第一个G,G0属于M而不属于任何一个P,G0的不指向可执行函数,而是在M进行调度时使用(使用G0的栈空间)

G-M-P的数量:#

  • G的数量可由runtime.NumGoroutine()获得,无数量限制
  • M的数量由语言本省动态控制,原则为保证每一个P可以被分配到一个可用的M(可用M = P),M会在不足时自动创建并在长时间空闲时(由 sysmon 触发)退出,M有理论数量上限(10000)
  • P的数量一般自动设置为=逻辑处理器数量,也可通过环境变量$GOMAXPROCS设置

GMP调度模型的优势:#

  1. 实现了M的高效复用,减少了系统线程创建与销毁的资源消耗
  2. 通过handoff与work stealing,实现了M的高效复用与负载均衡
  3. G可在不同的M中执行,且切换代价极低
  4. M通过在与自身关联的P中获取G,实现了lock free,减少了锁开销
线程模型与GMP调度模型
https://fuwari.vercel.app/posts/线程模型与gmp调度模型/
Author
7ac9d42
Published at
2025-11-24
License
CC BY-NC-SA 4.0