1.WaitGroup的作用
WaitGroup是Golang并发的两种方式之一,一个是Channel,另一个是WaitGroup。
WaitGroup的API只有3个,非常简单好用,但是有各种坑。
2.WaitGroup的用法
WaitGroup有3个API:
1)Add(delta int):增加/减少若干计数
2)Done:减少 1 个计数,等价于 Add(-1)
3)Wait:等待,直到计数等于 0
使用这三个API,可以进行并发控制。
当计数过少时,会panic;当计数过多时,也会发生 deadlock的panic。
简单例子如下:
var wg sync.WaitGroup
func foo1() {
log.Println("entry foo1")
time.Sleep(5 * time.Second)
wg.Done()
log.Println("exit foo1")
}
func foo2() {
log.Println("entry foo2")
time.Sleep(2 * time.Second)
wg.Done()
log.Println("exit foo2")
}
func main() {
log.Println("entry main")
wg.Add(1)
go foo1()
wg.Add(1)
go foo2()
log.Println("wg.Wait()")
wg.Wait()
log.Println("exit main")
}
3.陷阱避免
1)WaitGroup 同步的是 goroutine, 如果在 goroutine 中进行 Add(1) 操作,可能在这些 goroutine 还没来得及 Add(1) 已经执行 Wait 操作,造成程序退出。
2)WaitGroup 传递给goroutine的时候,应该采用引用方式,从而避免发生副本拷贝而死锁。