什么是GMP模型(简易版解释)

418 阅读2分钟

GMP模型是Go语言运行时(runtime)用来调度Goroutine执行的内部机制。它的目的是在多核心处理器上高效地调度成千上万的Goroutine。GMP模型由三个主要组成部分构成:Goroutine(G)、Machine(M)、和Processor(P)。下面是一个通俗的解释:

通俗理解:

想象一个快餐店,Goroutine(G)是顾客,Machine(M)是厨师,Processor(P)是厨房的工作站。每个工作站有自己的待做菜单(本地运行队列),顾客(G)来了就加入到一个工作站的菜单上。如果一个厨师(M)空闲,他就会从自己工作站的菜单上取一个菜来做(执行G)。如果厨师需要等待(比如等待食材),他会让出工作站,让另一个厨师来接手工作站,自己去处理等待的任务。等待完成后,他会尝试回到一个工作站继续工作。

  1. Goroutine(G):这是Go程序中的一个并发执行单元,你可以把它想象成一个非常轻量级的线程。Goroutine比标准的操作系统线程需要更少的资源,因此在一个程序中可以同时运行成千上万个Goroutine。

  2. Machine(M):这代表了一个内核级的线程,可以认为它是操作系统提供的线程。在GMP模型中,M是执行G代码的实际线程。每个M都会绑定一个P来执行G,除非它们正在执行系统调用。

  3. Processor(P):P可以看作是Goroutine执行的资源,它持有执行Goroutine所需的所有资源。你可以将P想象成一个执行Goroutine的权限令牌或者CPU的虚拟表示。P的数量通常由GOMAXPROCS环境变量控制,它决定了同时可以有多少Goroutine并行运行在CPU上。每个P都有自己的本地运行队列,存储着等待运行的Goroutine。

GMP工作流程简述:

  • 当一个Goroutine(G)被创建时,它会被放入到一个P的本地运行队列中。
  • 如果一个P有可运行的Goroutine,它会将其中一个Goroutine分配给一个空闲的M来执行。
  • 当M执行Goroutine时,如果Goroutine需要进行系统调用(比如文件操作),M可能会被阻塞。为了不浪费CPU时间,P会暂时脱离这个M,并寻找另一个空闲的M或者新建一个M,继续执行其他Goroutine。
  • 系统调用完成后,原来的M会尝试重新获取一个P来继续执行Goroutine,如果没有可用的P,M会进入空闲状态或执行全局运行队列中的Goroutine。

这个模型让Go能够在保持高并发的同时,有效利用CPU资源,执行大量的Goroutine。