author: ningan123
date: 2023-03-21 11:05
updated: 2023-03-21 11:09
官方文档对 WaitGroup 的描述是:一个 WaitGroup 对象可以等待一组协程结束。使用方法是:
wg.Add(delta int) 设置 worker 协程的个数,然后创建 worker 协程;wg.Done();wg.Wait() 且被 block,直到所有 worker 协程全部执行结束后返回。举一个例子来说明这个问题
下面三个小demo可以实现同样的功能,但是下一个都比上一个更加的优雅
package mainimport ("fmt""sync"
)// // 方法1
// func main() {
// for i := 0; i < 100; i++ {
// go fmt.Println(i)
// }
// time.Sleep(time.Second)
// }// // 方法2
// func main() {
// num := 100
// c := make(chan bool, num)
// for i := 0; i < num; i++ {
// go func(i int) {
// fmt.Println(i)
// c <- true
// }(i)
// }// for i := 0; i < num; i++ {
// <-c
// }
// }// 方法3
func main() {wg := sync.WaitGroup{}num := 20wg.Add(num)for i := 0; i < num; i++ {go func(i int) {// wg.Done() // 放这会有问题fmt.Println(i)// wg.Done()}(i)}wg.Wait()
}
对于方法3来说,wg.Done()要放在写成结束之后,否则就会有问题
当wg.Done()放在位置1处,如下为两次运行代码的结果。可以看到,很可能在协程还没有开始运行,主进程就结束了
############## wg.Done()放在位置1处 ##############
# go run main.go
9
2
0
# go run main.go
9
0
1
2
3
4
5
6
7
8
wg.Done()放在位置2处就没有问题了,每次当协程运行结束之后才将waitGroup中的协程减1,就不会有影响了~
# Golang sync.WaitGroup的用法
sync.WaitGroup 详解