请解释 Go 语言中 context 包的定义及其主要应用场景。它能解决并发编程中的哪些问题?
考察说明
考查对 Go 标准库 context 包核心概念和用途的理解。
回答思路
- 【回答框架 1】context 是 Go 标准库中用于传递取消信号、超时截止时间以及请求域元数据的接口。其核心接口是 context.Context,提供了 Done、Err、Deadline 和 Value 方法。
- 【回答框架 2】主要作用:一是取消传播,通过 context.WithCancel、context.WithTimeout 等派生 context,当父 context 取消时,子 context 也会自动取消,常用于 goroutine 的树状管理,避免资源泄露。
- 【回答框架 3】二是超时控制,context.WithTimeout 或 context.WithDeadline 可以设置执行时限,一旦超时,任何监听 Done 通道的 goroutine 都会收到通知,从而及时终止操作。
- 【回答框架 4】三是元数据传递,使用 context.WithValue 可以携带请求相关的键值对,但要避免传递可选参数和重要数据,因为这是非类型安全的。
- 【回答框架 5】在实际使用中,context.Context 通常作为函数的一个参数,惯用做法是将其作为第一个参数传递,并有明确的命名如 ctx。
- 【关键点 1】context.Context 接口包含 Done、Err、Deadline 和 Value 方法。
- 【关键点 2】context.WithCancel 返回一个可取消的 context 和 cancel 函数,调用 cancel 会通知所有派生的 context。
- 【关键点 3】context.WithTimeout 和 context.WithDeadline 用于设置超时,超时后自动取消。
- 【关键点 4】context.WithValue 用于传递请求作用域的元数据,但不应替代函数参数。
- 【关键点 5】不要将 context 存储在结构体中,应显式传递。
- 【易错点 1】忘记调用 cancel 函数可能导致资源未释放,需在创建后立即 defer cancel。
- 【易错点 2】context.WithValue 的 key 应使用自定义类型而非内置类型,以避免冲突。
- 【易错点 3】context 不能保证所有 goroutine 立即停止,需要配合 select 监听 Done 通道。