掌控并发:Go Context 的实战精要
在 Go 的并发世界中,context 是一个看似简单却至关重要的包。它不仅仅是传递取消信号,更是构建可控制、可维护并发系统的基石。
为什么需要 Context?
想象一个常见的场景:用户发起 HTTP 请求,后端需要查询数据库、调用多个微服务。如果用户中途关闭页面,后续操作应立即停止,释放资源。这正是 context 的核心作用——在 goroutine 树中传递取消信号、截止时间和元数据。
三个关键用法:
超时控制:避免请求无限等待
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() result, err := queryDatabase(ctx)取消传播:一键取消所有关联操作
func worker(ctx context.Context, ch chan<- Result) { select { case <-ctx.Done(): return // 收到取消信号立即退出 case result := <-process(): ch <- result } }值传递:安全地在调用链中传递请求域数据
ctx = context.WithValue(ctx, "requestID", "req-123")
最佳实践提醒:
- context 应作为函数的第一个参数
- 不要将 context 存储在结构体中
- 取消函数必须被调用,即使不使用其结果
- context.Value 应谨慎使用,仅传递请求域数据
Context 的设计体现了 Go 的哲学:通过简单的抽象解决复杂问题。掌握它,你就能写出更健壮、更可控的并发程序。