golang 使用WaitGroup的注意事项

var wg = sync.WaitGroup{}

func main() {
	c := make(chan int, 3)
	for i := 0; i<3; i++ {
		go func(i int) {
			wg.Add(1)
			defer wg.Done()
			c <- i
		}(i)
	}
	wg.Wait()
	close(c)
	fmt.Println("done")
}

如上所示,将wg.Add(1)写在go协程里面时,运行程序可能会出现“panic: send on closed channel”,原因在于go协程中的wg.Add(1)还没来得及执行,因此主协程中的wg.Wait()判断计数器已经为0,于是便执行close(c),导致协程中向channl 插入数据出现panic。
综上,正确做法是将wg.Add(1)写在go协程外面,如下所示:

var wg = sync.WaitGroup{}

func main() {
	c := make(chan int, 3)
	for i := 0; i<3; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			c <- i
		}(i)
	}
	wg.Wait()
	close(c)
	fmt.Println("done")
}

你可能感兴趣的:(golang)