go sync包的下的WaitGroup是用来实现goroutine的同步,阻塞等待所有的goroutine执行完后再继续向下执行。

当启动goroutine时,可能goroutine还没来执行,主进程已经结束了。下面是个简单的例子

func main() {
	for i:=0; i<=5;i++ {
		go func(i int) {
			fmt.Println(i)
		}(i)
	}
	fmt.Println("执行完成")
}

#输出
0
3
执行完成

从结果可以看到,只输出了0和3。主进程结束了,则协程也会结束。

WaitGroup

使用WaitGroup等待所有goroutine执行完成后继续向下执行

var wg sync.WaitGroup

func test(i int){
	defer wg.Done()
	fmt.Println(i)
}

func main() {
	for i:=0; i<5;i++ {
		wg.Add(1)
		go test(i)
	}
	wg.Wait()
	fmt.Println("执行完成")
}

#输出
2
1
3
4
0
执行完成

可以看到当所有grountine执行完后最后打印了执行完成。顺序不一致是因为这5个groutine是并发执行的,而groutine的调度是随机的。需要注意的是不要把wg.Add放到groutine中去执行

  • wg.Add() 相当于一个计数器,当启动一个goroutine就 +1
  • wg.Done() 当goroutine结束就 -1
  • wg.Wait() 等待所有的goroutine结束