在 golang 中,我了解的并发同步主要有两种方式,一种是 channel,另外一种就是我想说的 WaitGroup。Channel 大家都比较常见了,是 golang 中大家常说的 三驾马车 之一,这个我先不说,今天我想说说 WaitGroup 这兄弟。
WaitGroup 在 golang 中很简单,API 甚至只有可怜的三个,但是,功能却挺好用,甚至于都可以说可以省略到两个。下面我先来说说 WaitGroup 有什么用,或者说一个简单的用法是啥。
goroutine 监测
在使用 golang 中的 goroutine 的时候,有一个细节很容易被新手忽略,那就是很容易就让 主goroutine 返回了,从而导致其他的 goroutine 都被关闭了,也就没有所谓的并发了。很多新手为了防止 main goroutine 先返回,可能会使用这样的一段代码 goplay:
但是这段代码不是很友好,因为假设有某个 test 调用崩溃之后,那么其他执行 test 的 goroutine 可能就会永久卡住了,这在 golang 里面称为 goroutine泄露。如果此时,我们换用 WaitGroup,那么代码就会更友好一些了 goplay:
这就是简单的一个 WaitGroup 的使用方式,它在每个 goroutine 启动前增加一个计数,同时在每一个 goroutine 结束时递减计数。前面说了,它就只有 3 个简单的方法,分别是:
- Add(delta int):增加/减少若干计数
- Done:减少 1 个计数,等价于 Add(-1)
- Wait:卡住,直到计数等于 0
就是这么一个简单的组合,让我们在 goroutine 同步时能够启动非常大的帮助作用,而且在日常使用中也是很常用到。