WaitGroup 是 Go sync 包的轻量同步原语,需手动编排任务协调;Add 必须在 goroutine 启动前调用且不可并发,Done 应用 defer 保证执行。

WaitGroup 本身不是框架组件,而是 Go 标准库 sync 包里的一个轻量同步原语;它不提供调度、生命周期管理或错误聚合能力,所有“协调复杂并行任务”的逻辑必须由你手动编排。直接套用框架思维(比如“注入 WaitGroup”“自动等待”)反而容易引发 panic 或死锁。
WaitGroup.Add 必须在 goroutine 启动前调用,且不能并发调用
常见错误是把 Add(1) 放进 goroutine 内部,或在循环中漏掉、多调、错序调用:
- 如果
wg.Add(1)在go func() { ... }()之后执行,Wait()可能永远阻塞(计数器始终为 0) - 如果多个 goroutine 同时执行
wg.Add(1),而此时已有 goroutine 正在Wait(),Go 运行时会 panic 报错:sync: WaitGroup misuse: Add called concurrently with Wait - 正确姿势:循环体外确定总任务数,或在启动每个 goroutine 前立刻调用
Add(1),且确保无竞态
Done 必须保证执行,且不能重复调用
defer wg.Done() 是最安全的写法,但要注意闭包捕获变量的问题:
错误示例:
Done()
- 超时:用
select+time.After()包裹wg.Wait(),否则主线程可能无限挂起 - 取消:需额外传入
context.Context,并在每个 goroutine 中监听ctx.Done() - 错误收集:不能依赖
WaitGroup自身,要配合chan error或切片 + 互斥锁(sync.Mutex)汇总
例如,简单错误收集推荐用带缓冲的 channel(容量 = 任务数),避免 goroutine 因发送阻塞而无法退出:
sync.WaitGroup
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











