Context 有什么作用,和 WaitGroup 有什么区别?
Context 有什么作用,和 WaitGroup 有什么区别?
提示
题眼: 通道 + 树状结构,重点讲源码和使用场景。
Context 主要用于父子协程之间同步状态和传递上下文信息,WaitGroup 主要用于让主协程等待多个子协程执行完成。
WaitGroup 的工作状态:

Context 的工作状态:

Context 是一种让多级 goroutine 协同工作的工具,底层依赖 Channel,因此也是并发安全的。
最常见的使用场景有两个:
- 父 goroutine 向子孙 goroutine 广播取消信号。
- 父 goroutine 向子孙 goroutine 传递必要的上下文数据。
需要注意的是,Context 的控制关系是自上而下的,每一级只能影响自己的子孙级,不能反向控制父级或同级。
type Context interface {
// Deadline 返回截止时间,以及是否设置过截止时间
Deadline() (deadline time.Time, ok bool)
// Done 返回一个只读通道,用于接收取消信号
Done() <-chan struct{}
// Err 在 Context 被取消后返回具体原因
Err() error
// Value 用于读取上下文中的键值对
Value(key interface{}) interface{}
}重要
参考答案:
Context 和 WaitGroup 的核心区别在于职责不同。WaitGroup 解决的是“等一组协程执行完”,而 Context 解决的是“在一组有关联的协程之间传递取消信号、超时信息和上下文数据”。
Context 本身是一个接口,最常用的方法有四个:Deadline、Done、Err 和 Value。其中最关键的是 Done,它会返回一个只读通道,谁监听这个通道,谁就可以在上层取消任务时及时退出。
官方常见的几种 Context 里,Background 和 TODO 都可以作为根 Context;WithCancel 可以创建一个可手动取消的 Context;WithDeadline 和 WithTimeout 在它的基础上补充了截止时间和超时能力;WithValue 则用于向下传递键值对。
WaitGroup 更偏向同步工具,只负责等待,不负责取消,也不负责传递错误和上下文信息。所以如果业务里有“一个协程出错,其他协程也要尽快退出”的需求,通常要结合 errgroup 和 Context 一起使用。
