Go的GPM模型(Goroutine, P, M)是一种用于管理并发执行的调度模型,有助于充分利用多核处理器,并提供高效的并发编程体验。以下是对GPM模型的详细介绍:

  1. Goroutine(G)
    • Goroutine是Go中的轻量级线程。它比传统操作系统线程更加轻量,允许创建数千甚至数百万个Goroutines而不会导致过多的资源开销。
    • 每个Goroutine都有自己的栈空间,通常很小,以便更快地创建和销毁。
    • Goroutines之间通过通道(Channels)进行通信和同步。
  2. 机器线程(M)
    • 机器线程是底层操作系统线程的抽象。Go运行时(runtime)使用机器线程来执行Goroutines。
    • Go运行时会维护一组M,通常数量等于处理器核心的数量。这允许Go有效地利用多核处理器。
    • M负责在处理器上执行Goroutines。
  3. 调度器(P)
    • 调度器是Go运行时的一部分,用于协调Goroutines和机器线程的分配和执行。
    • P负责将Goroutines分配给可用的M,并确保它们在处理器上运行。
    • 调度器还负责在某些情况下(例如Goroutine阻塞)将M与其他可运行的Goroutines关联,以提高并发性能。
  4. GPM协作
    • G、P和M之间的协作是Go调度模型的核心。每个M都与一个P相关联,而P可以在多个M之间轮换。
    • M执行与之相关联的Goroutines,但P可以将M从一个Goroutine切换到另一个Goroutine,以实现Goroutines的调度。
    • 当某个Goroutine在等待IO、休眠或阻塞时,P可以将M与其他可运行的Goroutines相关联,以充分利用处理器。
  5. 抢占式调度
    • Go的调度模型是抢占式的,这意味着调度器可以在Goroutine之间进行抢占式切换。
    • 这允许Go在多核处理器上高效利用资源,不会因为某个Goroutine执行耗时操作而阻塞其他Goroutines。
  6. 运行时环境
    • 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
  1. Goroutines (G):
    • 图示中有三个Goroutines,分别标记为Goroutine 1、Goroutine 2和Goroutine 3。
    • 这些Goroutines代表Go程序中的并发任务,它们可以同时执行不同的操作。
  2. 机器线程 (M):
    • 机器线程是底层操作系统线程的抽象。在图示中,有三个机器线程,标记为Machine Thread 1、Machine Thread 2和Machine Thread 3。
    • 每个机器线程负责执行分配给它的Goroutines。
  3. 调度器 (P):
    • 调度器是Go运行时的一部分,用于协调Goroutines和机器线程的分配和执行。在图示中,有两个调度器,标记为Scheduler P1和Scheduler P2。
    • 调度器负责将Goroutines分配给可用的机器线程(M)来执行。
  4. 调用过程:
    • 调用过程是动态的,它描述了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: 恋水无意