2-3.sync.WaitGroup
sync.WaitGroup
可以等待一组 Goroutine 的返回,一个比较常见的使用场景是批量发出 RPC 或者 HTTP 请求:
结构体
sync.WaitGroup
结构体中只包含两个成员变量,一个是计数器,一个是信号量,甚至连锁都没有
sync.noCopy
是一个特殊的私有结构体,tools/go/analysis/passes/copylock
包中的分析器会在编译期间检查被拷贝的变量中是否包含 sync.noCopy
或者实现了 Lock
和 Unlock
方法,如果包含该结构体或者实现了对应的方法就会报出以下错误:copies lock value: sync.WaitGroup
接口
sync.WaitGroup
对外暴露了三个方法:sync.WaitGroup.Add
、sync.WaitGroup.Wait
和 sync.WaitGroup.Done
。
因为其中的 sync.WaitGroup.Done
只是向 sync.WaitGroup.Add
方法传入了 -1,所以我们重点分析另外两个方法,即 sync.WaitGroup.Add
和 sync.WaitGroup.Wait
。
Add()
方法做两件事:
增加或扣减计数器(
Add(正数)
时增加,Done()
时扣减)扣减计数器后检查计数器,在计数器扣减为
0
时唤醒所有睡眠的协程
Wait()
方法只做一件事:增加计数器并让协程进入休眠
小结
sync.WaitGroup.Done
只是对sync.WaitGroup.Add
方法的简单封装,我们可以向sync.WaitGroup.Add
方法传入任意负数(需要保证计数器非负)快速将计数器归零以唤醒等待的协程可以同时有多个协程等待当前
sync.WaitGroup
计数器的归零,这些 Goroutine 会被同时唤醒;
Last updated