Go的GPM模型(Goroutine, P, M)是一种用于管理并发执行的调度模型,有助于充分利用多核处理器,并提供高效的并发编程体验。以下是对GPM模型的详细介绍:
- Goroutine(G):
- Goroutine是Go中的轻量级线程。它比传统操作系统线程更加轻量,允许创建数千甚至数百万个Goroutines而不会导致过多的资源开销。
- 每个Goroutine都有自己的栈空间,通常很小,以便更快地创建和销毁。
- Goroutines之间通过通道(Channels)进行通信和同步。
- 机器线程(M):
- 机器线程是底层操作系统线程的抽象。Go运行时(runtime)使用机器线程来执行Goroutines。
- Go运行时会维护一组M,通常数量等于处理器核心的数量。这允许Go有效地利用多核处理器。
- M负责在处理器上执行Goroutines。
- 调度器(P):
- 调度器是Go运行时的一部分,用于协调Goroutines和机器线程的分配和执行。
- P负责将Goroutines分配给可用的M,并确保它们在处理器上运行。
- 调度器还负责在某些情况下(例如Goroutine阻塞)将M与其他可运行的Goroutines关联,以提高并发性能。
- GPM协作:
- G、P和M之间的协作是Go调度模型的核心。每个M都与一个P相关联,而P可以在多个M之间轮换。
- M执行与之相关联的Goroutines,但P可以将M从一个Goroutine切换到另一个Goroutine,以实现Goroutines的调度。
- 当某个Goroutine在等待IO、休眠或阻塞时,P可以将M与其他可运行的Goroutines相关联,以充分利用处理器。
- 抢占式调度:
- Go的调度模型是抢占式的,这意味着调度器可以在Goroutine之间进行抢占式切换。
- 这允许Go在多核处理器上高效利用资源,不会因为某个Goroutine执行耗时操作而阻塞其他Goroutines。
- 运行时环境:
- Go运行时(runtime)是Go程序的一部分,负责管理Goroutines、调度器和机器线程,以确保它们协同工作。
- Go运行时还处理垃圾回收、内存管理和其他底层任务。
下图展示了Go的GPM模型的关键组成部分以及它们之间的关系:
graph LR
subgraph GoProgram
A[Goroutine 1]
B[Goroutine 2]
C[Goroutine 3]
end
subgraph Runtime
P1[Scheduler P1]
P2[Scheduler P2]
end
subgraph MachineThreads
M1[Machine Thread 1]
M2[Machine Thread 2]
M3[Machine Thread 3]
end
A -->|Assigned to| M1
B -->|Assigned to| M2
C -->|Assigned to| M1
P1 -->|Manages| M1
P2 -->|Manages| M2
P1 -->|Manages| M3
M1 -->|Executes| A
M2 -->|Executes| B
M3 -->|Executes| C
- Goroutines (G):
- 图示中有三个Goroutines,分别标记为Goroutine 1、Goroutine 2和Goroutine 3。
- 这些Goroutines代表Go程序中的并发任务,它们可以同时执行不同的操作。
- 机器线程 (M):
- 机器线程是底层操作系统线程的抽象。在图示中,有三个机器线程,标记为Machine Thread 1、Machine Thread 2和Machine Thread 3。
- 每个机器线程负责执行分配给它的Goroutines。
- 调度器 (P):
- 调度器是Go运行时的一部分,用于协调Goroutines和机器线程的分配和执行。在图示中,有两个调度器,标记为Scheduler P1和Scheduler P2。
- 调度器负责将Goroutines分配给可用的机器线程(M)来执行。
- 调用过程:
- 调用过程是动态的,它描述了Goroutines如何被分配到机器线程并执行。
- 例如,Goroutine 1被分配给Machine Thread 1,Goroutine 2被分配给Machine Thread 2,Goroutine 3又被分配给Machine Thread 1。
- 这些分配和切换是由调度器(P)来管理的,以便高效地利用多核处理器。
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意