GoLang教程——Context上下文实战

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

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

(译)Go并发模式——Context

原文地址: https://go.dev/blog/context[] 作者:Sameer Ajmani 时间:29 July 2014 简介 footnote:ddns[这篇文章是go官网博客中的一篇,尽管文章比较早,但是较详细的描述了 context 出现的原因、使用方式,仍然值得一读。] 在 Go 服务器中,每个传入的请求都在其自己的 goroutine 中处理。请求处理程序通常会启动额外的 goroutine 来访问数据库和 RPC 服务等后端。处理请求的一组 goroutine 通常需要访问特定于请求的值,例如最终用户的身份、授权令牌和请求的截止日期。当请求被取消或超时时,所有处理该请求的 goroutines 都应该快速退出,以便系统可以回收它们正在使用的任何资源。 在 Google,我们开发了一个 context 包,可以轻松地将请求范围的值、取消信号和截止日期等跨 API 边界传递给正在处理请求的所有 goroutine。 https://go.dev/pkg/context[该软件包] 作为context公开可用 。本文介绍了如何使用该包并提供了一个完整的工作示例。 Context context 包的核心是 Context 类型: 1type Context interface { // <1> 2 Done() <-chan struct{} // <2> 3 4 Err() error // <3> 5 6 Deadline() (deadline time.Time, ok bool) // <4> 7 8 Value(key interface{}) interface{} // <5> 9} <1> Context 携带截止日期、取消信号和请求范围的跨越 API 边界的值,多个 goroutine 同时使用它的方法是安全的。 <2> Done 返回一个在此 Context 取消或超时时的通道(chan) <3> Err 错误信息说明 context 为什么被取消, 在 Done 返回的 chan 被关闭之后获取 <4> Deadline 返回 Context 被取消的时间 <5> Value 返回参数 key 关联的值,没有则返回 nil ...

2022-07-19 · 5 min · 1012 words · Hank