个人技术博客

Go 并发模型浅析:从 goroutine 到 GMP 调度

发布于 2026-08-05 · 分类:Go

Go 的并发能力来源于语言层面的 goroutine 与运行时调度器。本文不贴大段源码,只讲清核心思路。

为什么 goroutine 足够轻量

goroutine 初始栈仅几 KB,按需增长;由 Go 运行时(而非操作系统)负责调度,创建与切换成本远低于线程。因此一个进程内开成千上万个 goroutine 很常见。

GMP 三件套

调度器把 G 放到 P 的本地队列,M 从队列取 G 执行;遇到系统调用时,M 会被解绑,让出 P 给其他 M,从而减少阻塞浪费。

一个简单示例

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(n int) {
            defer wg.Done()
            fmt.Println("hello", n)
        }(i)
    }
    wg.Wait()
}

常见误区

闭包循环变量捕获、无节制开 goroutine 导致资源耗尽、直接共享变量而不加同步,都是新手常见问题。并发编程的第一原则:能用 channel 表达就用 channel,不要裸共享内存。

← 返回首页