Files
cs-note/hzh/GolangStar/Go语言原理/gmp调度原理/gmp-summary.md
T

3.5 KiB
Raw Blame History

tags, create time
tags create time
go
golang
go-principle
gmp-scheduler
summary
cheat-sheet
2026-06-07 16:00

GMP 调度原理 — 知识卡片

概述

本节汇总 GMP 调度模型的全景流程与核心要点,适合作为复习回顾的速查卡片。涵盖 §6:完整生命周期流程图和关键概念总结。

正文

6.1 GMP 全景流程

flowchart TD
    subgraph Create["创建 goroutine"]
        NewProc["runtime.newproc<br/>systemstack → newproc1<br/>runqput → LRQ/GRQ"]
    end

    subgraph Schedule["调度循环"]
        ScheduleFn["schedule → findRunnable"]
        FindR["findRunnable: LRQ → GRQ → netpoll → steal"]
        Execute["execute → gogo(g)"]
    end

    subgraph Yield["让出执行权"]
        End["goexit1 → goexit0<br/>status=Gdead, gfput"]
        Gosched["Gosched → gosched_m<br/>status=Grunnable, globrunqput"]
        Park["gopark → park_m<br/>status=Gwaiting, 上层管理"]
    end

    subgraph Preempt["抢占 sysmon"]
        Sysmon["sysmon 线程"]
        Retake["retake: syscall + timeout"]
        Collab["协作式: stackPreempt"]
        Signal["非协作式: sigPreempt"]
    end

    subgraph Recover["恢复执行"]
        Ready["goready → ready<br/>status=Grunnable, runqput"]
    end

    Create --> Schedule
    Schedule --> Yield
    Yield --> Recover
    Recover --> Schedule
    Sysmon --> Preempt
    Preempt --> Yield
    style Create fill:#e3f2fd
    style Schedule fill:#e8f5e9
    style Yield fill:#fff3e0
    style Preempt fill:#ffebee
    style Recover fill:#e8f5e9

6.2 核心要点速查

维度 要点
角色分工 G = 任务(goroutine),M = 工人(OS 线程),P = 主管(逻辑处理器)
队列优先级 LRQ(无锁 CAS)> GRQ(加锁)> netpoll(IO)> steal(工作窃取)
防饥饿 每 61 次调度强制检查一次 GRQ
LRQ 容量 256 个 G;满时触发 runqputslow 批量迁移至 GRQ
runnext VIP 位置,新创建的 G 优先放入,下次调度直接执行
协程状态机 _Gidle → _Grunnable → _Grunning → { _Gdead / _Gwaiting / _Gsyscall }
让渡方式 结束→回收到 gfree;Gosched→入 GRQ;gopark→_Gwaiting 由上层保管
唤醒机制 goready → ready:改状态→runqput→wakep()
系统调用抢占 reentersyscall 解绑 P/M;exitsyscall 快速路径复用 oldP / 慢速路径重新分配
协作式抢占 设置 stackPreempt,在函数调用/栈检查时响应
非协作式抢占 Go ≥ 1.14,通过 POSIX 信号注入 asyncPreempt,绕过函数调用依赖
sysmon 三板斧 netpoll(IO 轮询)→ retake(抢占检查)→ GC 触发

6.3 关键数据记忆点

数字 含义
256 LRQ 最大容量
61 每次 GRQ 强制检查间隔(schedtick)
10ms syscall 超时阈值、运行抢占阈值(forcePreemptNS)
4 work-stealing 最大试探轮数
128 netpoll epoll_wait 单次最多返回事件数

关联笔记