Golang WaitGroup使用指南
在Golang中使用WaitGroup时遇到了一些困惑:
- 为什么有时候WaitGroup的计数器会变成负数?
- 如何正确使用Add()和Done()方法来避免死锁?
- 在主goroutine中调用Wait()后,子goroutine还没执行完怎么办?
- WaitGroup和channel配合使用时有什么需要注意的?
- 有没有常见的WaitGroup使用错误示例可以参考?
希望能得到一些实际代码示例和最佳实践建议。
2 回复
Golang WaitGroup 使用指南
WaitGroup 是 Go 语言 sync 包中的一个重要同步原语,用于等待一组 goroutine 完成执行。
核心方法
var wg sync.WaitGroup
// 添加等待的 goroutine 数量
wg.Add(delta int)
// 标记一个 goroutine 完成
wg.Done()
// 阻塞等待所有 goroutine 完成
wg.Wait()
基本使用模式
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // 确保在函数退出时调用
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second) // 模拟工作
fmt.Printf("Worker %d done\n", id)
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 3; i++ {
wg.Add(1) // 每启动一个 goroutine 前增加计数
go worker(i, &wg)
}
wg.Wait() // 等待所有 worker 完成
fmt.Println("All workers completed")
}
重要注意事项
- Add 必须在 Wait 之前调用
- Done 调用次数必须与 Add 的总数匹配
- WaitGroup 应通过指针传递给 goroutine
- 不要复制 WaitGroup(会导致竞态条件)
常见错误模式
// 错误:在 goroutine 内部调用 Add
go func() {
wg.Add(1) // 竞态条件!
defer wg.Done()
// ...
}()
// 正确:在启动 goroutine 前调用 Add
wg.Add(1)
go func() {
defer wg.Done()
// ...
}()
实际应用场景
- 并行处理批量任务
- 等待多个后台服务启动完成
- 并发执行多个网络请求
WaitGroup 是 Go 并发编程的基础工具,正确使用可以确保程序正确同步,避免 goroutine 泄漏。


