4. sync.WaitGroup 原理
sync.WaitGroup 是 Go 语言提供的内置并发安全的等待组,开箱即用。sync.WaitGroup 的原理非常简单,只有三个方法,Add、Done 和 Wait。Add 方法用于添加等待的任务数,Done 方法用于减少等待的任务数,Wait 方法用于等待所有任务执行完毕。
sync.WaitGroup 的内部结构如下:
type WaitGroup struct {
noCopy noCopy
state1 [3]uint32
}
sync.WaitGroup 内部有一个 state1 数组,数组的长度为 3,分别用于存储等待的任务数、完成的任务数和信号量。
4.1 sync.WaitGroup 的 Add 方法
sync.WaitGroup 的 Add 方法用于添加等待的任务数,其原型如下:
func (wg *WaitGroup) Add(delta int)
Add 方法的实现非常简单,只有两个步骤:
- 将 delta 加到等待的任务数上
- 如果 delta 小于 0,则 panic
4.2 sync.WaitGroup 的 Done 方法
sync.WaitGroup 的 Done 方法用于减少等待的任务数,其原型如下:
func (wg *WaitGroup) Done()
Done 方法的实现非常简单,只有两个步骤:
- 将完成的任务数加 1
- 如果完成的任务数大于等于等待的任务数,则 panic
4.3 sync.WaitGroup 的 Wait 方法
sync.WaitGroup 的 Wait 方法用于等待所有任务执行完毕,其原型如下:
func (wg *WaitGroup) Wait()
Wait 方法的实现非常简单,只有两个步骤:
- 如果等待的任务数为 0,则直接返回
- 如果等待的任务数不为 0,则等待信号量
5. sync.WaitGroup 的使用
sync.WaitGroup 的使用非常简单,直接声明变量即可,不需要初始化。sync.WaitGroup 的声明如下:
var wg = sync.WaitGroup{}
sync.WaitGroup 的操作如下:
wg.Add(1) // 添加等待的任务数
wg.Done() // 减少等待的任务数
wg.Wait() // 等待所有任务执行完毕
6. sync.WaitGroup 的注意事项
- sync.WaitGroup 不能在创建后再进行复制操作。
- sync.WaitGroup 与其他结构不同,它不是一个结构体,因此我们在声明的时候只需要声明变量即可,不需要初始化。