GMP 模型详解

6 min read

GMP模型是Go语言的并发调度模型,它由三个主要组成部分构成:G(Goroutine)、M(Machine)和P(Processor)。在Go中,GMP模型帮助管理和调度goroutine的执行,确保并发性能和高效利用计算资源。下面是GMP模型的详细解释:

  1. G(Goroutine):G表示goroutine,它是Go语言的基本并发单位。一个goroutine是一个轻量级线程,可以并发执行一个函数。goroutine的堆栈空间较小(初始值一般在2KB左右),因此可以在一个程序中创建大量的goroutine。Go的运行时系统(runtime)负责goroutine的调度和管理。
  2. M(Machine):M表示操作系统线程。M是一个物理实体,它负责执行goroutine。Go运行时将goroutine与操作系统线程关联,实际执行goroutine代码的是操作系统线程。在Go的调度器中,会根据需要创建或销毁操作系统线程,并根据goroutine的数量和系统负载动态调整线程数。
  3. P(Processor):P表示逻辑处理器。P是一个调度实体,它负责调度和分配goroutine到操作系统线程(M)上执行。在Go中,逻辑处理器的数量通常与机器的CPU核心数相同,这样可以最大化地利用计算资源。每个逻辑处理器都有一个本地的goroutine队列,当一个goroutine被调度时,它会从本地队列中取出一个goroutine并与操作系统线程关联。

GMP模型的工作原理如下:

  • 当一个goroutine被创建时,它首先被放入P的本地队列。
  • P会选择一个可用的M(操作系统线程),将队列中的goroutine分配给M执行。
  • 如果所有M都在执行goroutine,P会将该goroutine放入全局队列,待有可用的M时再进行调度。
  • 如果一个goroutine因为阻塞(例如等待I/O)而无法继续执行,M会解除与该goroutine的关联,并通知P调度其他goroutine。
  • 当阻塞的goroutine重新准备就绪时,它会被放入P的本地队列或全局队列中,等待再次被调度。

GMP模型是Go语言并发调度的核心,它通过将goroutine、操作系统线程和逻辑处理器分离,使得Go运行时能够高效地管理和调度并发任务,从而在保证性能的同时降低资源消耗。