GoLang教程——Context上下文实战

在 Go 的并发编程中,context(上下文)包是绝对的核心。无论是处理 HTTP 请求、RPC 调用,还是数据库查询,Context 都扮演着控制 Goroutine 生命周期的角色。 简而言之,Context 主要解决三个问题: 1. 取消信号:通知子 Goroutine 停止工作,释放资源。 2. 超时控制:规定任务必须在多长时间内完成,否则强制取消。 3. 数据传递:在调用链中传递请求范围内的元数据(如 UserID, TraceID)。 1. 为什么需要 Context? 假设你启动了一个 Goroutine 去查询数据库,如果用户突然关闭了浏览器,或者请求处理太慢超时了,你希望这個后台查询任务能立即停止,而不是继续浪费数据库资源。这就是 Context 的用武之地。 Go 的设计原则:谁启动了 Goroutine,谁就有责任(通过 Context)管理它的退出。 2. 超时控制 (WithTimeout) 这是 Context 最常用的场景。 package main import ( "context" "fmt" "time" ) func main() { // 1. 创建一个带超时的 Context // 规定任务必须在 2 秒内完成,否则 ctx 会收到取消信号 ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) // 关键:函数结束时必须调用 cancel,防止内存泄漏 defer cancel() fmt.Println("Start working...") // 2. 将 ctx 传递给耗时任务 doSlowWork(ctx) } func doSlowWork(ctx context.Context) { // 模拟一个需要 3 秒才能完成的任务 // Select 会等待 done 信号或者 work 完成,以此来实现超时抢占 select { case <-time.After(3 * time.Second): // 模拟业务逻辑 fmt.Println("Work done successfully!") case <-ctx.Done(): // 监听 Context 的取消信号 // 如果超时了,ctx.Err() 会返回 DeadlineExceeded fmt.Println("Work cancelled:", ctx.Err()) } } ...

2025-03-02 · 2 min · 303 words · Hank