章节

10.1 协程

本篇学习 goroutine 的启动方式与主协程退出影响,并能编写最小并发示例。

协程

概念说明

Go 中的协程通常指 goroutine
使用 go 关键字可以让一个函数并发执行。

初学时可以先把 goroutine 理解成“一个可以和当前代码同时推进的轻量任务”。
它和操作系统线程不是完全一样的概念,但在学习并发时,你可以先抓住重点:
goroutine 启动后,不会堵住当前代码继续往下走。

需要特别注意:
如果 main 函数结束,整个程序会退出,未执行完的 goroutine 也会一起结束。

语法/规则

  1. 使用 go 函数调用 启动一个 goroutine。
  2. goroutine 的执行顺序由调度器决定,不要依赖固定顺序。
  3. main 函数不会自动等待其他 goroutine。
  4. 需要等待任务结束时,应使用 sync.WaitGroup、channel 或其他同步方式。
  5. 多个 goroutine 共享变量时,要考虑线程安全问题。

语法模板

1
go 函数名(参数列表)

启动 goroutine 示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package main

import (
	"fmt"
	"time"
)

func printTask(name string) {
	for i := 1; i <= 3; i++ { // 每个任务打印 3 次
		fmt.Println(name, i)
	}
}

func main() {
	go printTask("goroutine") // 启动一个新的 goroutine 去执行 printTask("goroutine")
	printTask("main")         // 主 goroutine 不会等待上一行执行完,而是立刻继续执行这里

	time.Sleep(100 * time.Millisecond) // 临时等一小会儿,避免 main 过早结束
}

输出结果(顺序可能不同):

1
2
3
4
5
6
main 1
goroutine 1
main 2
goroutine 2
main 3
goroutine 3

也可能是:

1
2
3
4
5
6
main 1
main 2
main 3
goroutine 1
goroutine 2
goroutine 3

注意这个细节

go printTask("goroutine") 不是先把这个函数执行完再往下走。
它只是启动一个新的 goroutine,主 goroutine 会立刻继续执行 printTask("main"),所以两边可能同时推进。

从运行结果就能看出来,它们不是固定顺序执行:

1
2
3
4
5
6
main 1
goroutine 1
main 2
goroutine 2
main 3
goroutine 3

也可能是:

1
2
3
4
5
6
main 1
main 2
main 3
goroutine 1
goroutine 2
goroutine 3

常见错误

  1. 启动 goroutine 后立即让 main 结束,导致后台任务还没来得及执行。
  2. 依赖并发输出的固定顺序,实际不同机器或不同运行次数可能不一样。
  3. 多个 goroutine 同时修改同一个变量却不加同步保护,容易产生数据竞争。
本文禁止转载
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
最近构建时间:2026-04-17 19:07:48 CST
载入天数...载入时分秒...
发表了 1 篇文章 · 发表了 152 篇笔记 · 总计 18 万 0 千字