WaitGroup
概念说明
sync.WaitGroup 用于等待一组 goroutine 完成。
它内部维护一个计数器:任务开始前增加计数,任务结束后减少计数,主流程等待计数归零。
语法/规则
Add(n)表示增加 n 个待完成任务。Done()表示一个任务完成,通常配合defer使用。Wait()会阻塞,直到计数器归零。Add通常要在启动 goroutine 之前调用。Add和Done次数必须匹配,否则可能死锁或 panic。
等待多个任务示例
| |
输出结果(任务顺序可能不同):
| |
怎么理解这个示例
- 这段代码的核心流程是:先登记 3 个任务,再并发执行它们,最后统一等待它们全部结束。
done一定会在所有task输出之后出现,因为主 goroutine 会卡在wg.Wait(),不会提前往下执行。task 1、task 2、task 3的先后顺序不固定,因为 goroutine 的调度顺序不是手动控制的。
场景示例:并发下载多个文件后,再进入下一步
假设程序要同时下载 3 个文件。
下载可以并发进行,但“开始打包”这一步必须等 3 个文件都下载完成后才能继续。
| |
输出结果(顺序可能不同):
| |
WaitGroup 在这里起到什么作用
- 3 个文件可以同时下载,所以前面的下载任务适合用 goroutine 并发执行。
- 但
start package不能太早执行,否则可能还有文件没下载完。 WaitGroup的作用就是:让主 goroutine 等所有下载任务都完成后,再继续下一步。- 它的独特点是只负责“等全部做完”,不负责传递结果,也不负责控制执行顺序。
常见错误
- 在 goroutine 内部调用
Add,主流程可能先执行到Wait,造成时序问题。 - 忘记调用
Done,导致Wait一直阻塞。 Done调用次数多于Add,会导致计数器变成负数并触发 panic。- 循环启动 goroutine 时没有把循环变量作为参数传进去,容易读到意外值。