Z
ZHANK
并发编程

Goroutine 协程

go 关键字启动协程、轻量级线程、GMP 调度模型简介

Goroutine 协程

go 关键字启动一个 goroutine——轻量级协程,Go 运行时自动调度到 OS 线程上。启动成本极低(几 KB),可以同时运行数十万个。

学完本章你将: 掌握 go 关键字、goroutine 模型、GMP 调度简介。


启动 goroutine

go
package main

import (
    "fmt"
    "time"
)

func say(msg string) {
    for i := 0; i < 3; i++ {
        fmt.Println(msg, i)
        time.Sleep(100 * time.Millisecond)
    }
}

func main() {
    go say("hello")   // 在新的 goroutine 中运行
    say("world")      // 在 main goroutine 中运行

    // 等待 goroutine 完成(实际开发用 sync.WaitGroup)
    time.Sleep(time.Second)
}

goroutine vs 线程

GoroutineOS 线程
初始栈大小~2KB~1MB
栈可增长是(动态)固定
创建成本极低高(内核调用)
调度Go 运行时(用户态)OS 内核
同时运行数十万无压力数千就很吃力

等待 goroutine 完成

go
// ❌ 用 time.Sleep —— 不可靠
// ✅ 用 sync.WaitGroup
var wg sync.WaitGroup

for i := 0; i < 5; i++ {
    wg.Add(1)  // 计数器 +1
    go func(n int) {
        defer wg.Done()  // 完成时 -1
        fmt.Println(n)
    }(i)
}

wg.Wait()  // 等待所有 goroutine 完成
fmt.Println("全部完成")

GMP 调度模型简介

G — Goroutine(协程)
M — Machine(OS 线程)
P — Processor(逻辑处理器,默认 = CPU 核数)

GOMAXPROCS 控制 P 的数量(默认等于 CPU 核心数)