GPM调度模型
Go 语言的 GPM 调度模型是 Go 运行时中用于处理并发的核心机制之一,它将 Goroutine(轻量级线程)有效地映射到系统线程上,以最大化并发性能。GPM 模型主要由三个部分组成:G(Goroutine)、P(Processor)、M(Machine)。让我们逐一详细介绍:
1. G(Goroutine)
- Goroutine 是 Go 语言中用于并发执行的轻量级线程,每个 Goroutine 都有自己的栈和上下文信息。
- Goroutine 相对于操作系统的线程更加轻量级,可以在同一时间内运行成千上万的 Goroutine。
2. P(Processor)
- P 是处理 Goroutine 的调度器的上下文,每个 P 包含一个本地运行队列(Local Run Queue),用于存储需要运行的 Goroutine。
- P 的数量由
GOMAXPROCS
设置决定,它决定了并行执行的最大线程数。 - P 不仅管理 Goroutine,还负责与 M 协作,将 Goroutine 分配给 M 执行。
3. M(Machine)
- M 代表操作系统的线程,负责执行 Goroutine。一个 M 一次只能执行一个 Goroutine。
- M 是实际执行代码的工作单元,M 与 P 绑定后才能执行 Goroutine。
- M 可以通过调度器从全局运行队列中拉取新的 Goroutine,也可以与其他 M 协作完成工作。
4. GPM 模型的调度过程
- 调度器工作机制:Goroutine 创建后会被放入 P 的本地队列,P 会从该队列中选择 Goroutine,并将其分配给 M 执行。如果本地队列为空,P 可以从全局运行队列或其他 P 的队列中窃取任务。
- 工作窃取机制:如果一个 P 的本地队列为空,而另一个 P 的本地队列中有多个 Goroutine,前者可以从后者中窃取任务,从而保持系统的高效利用率。
- 阻塞与调度:当 M 执行的 Goroutine 阻塞(例如 I/O 操作)时,M 会释放当前的 P 并等待 P 重新分配任务,从而避免资源浪费。
5. 模型优点
- 高效的并发调度:GPM 模型使得 Go 语言可以高效地管理数百万个 Goroutine 的并发执行。
- 可伸缩性:通过 P 与 M 的动态调度,GPM 模型可以充分利用多核处理器的性能。
- 轻量级:Goroutine 非常轻量,创建和切换的成本比系统线程要低得多。