Bootstrap

从源码角度详解Golang调度GMP

从源码角度详解Golang调度GMP

1.1 调度器的三个抽象概念:G、M、P

  • G:代表一个 goroutine,每个 goroutine 都有自己独立的栈存放当前的运行内存及状态。可以把一个 G 当做一个任务。
  • M: 代表内核线程(Pthread),它本身就与一个内核线程进行绑定,goroutine 运行在 M 上。
  • P:代表一个处理器,可以认为一个“有运行任务”的 P 占了一个 CPU 线程的资源,且只要处于调度的时候就有 P。

注:内核线程和 CPU 线程的区别,在系统里可以有上万个内核线程,但 CPU 线程并没有那么多,CPU 线程也就是 Top 命令里看到的 CPU0、CPU1、CPU2…的数量。

三者关系大致如下图:

image

图 1、图 2 代表 2 个有运行任务时的状态。M 与一个内核线程绑定,可运行的 goroutine 列表存放到 P 里面,然后占用了一个 CPU 线程来运行。

图 3 代表没有运行任务时的状态,M 依然与一个内核线程绑定,由于没有运行任务因此不占用 CPU 线程,同时也不占用 P。

1.2 调度的大致轮廓

;