sync.WaitGroup Add( ) 用法

发布时间 2023-07-10 16:20:45作者: 熟稔于纸

使用sync.WaitGroup来实现并发任务的同步。
image
Done()通常在函数内使用defer wg.Done()调用。add()学习是我通常也放在函数内,今天我发现在函数内调用会出现问题,主进程会先执行,比如如下代码,会出现问题。

package main

import (
	"fmt"
	"sync"
)

var n int
var wg sync.WaitGroup

func f1() {
	defer wg.Done()
	wg.Add(1)
	for i := 0; i < 1000; i++ {
		n = n + 1
	}
	fmt.Println("f1", n)
}
func f2() {
	defer wg.Done()
	wg.Add(1)
	for i := 0; i < 1000; i++ {
		n = n + 1
	}
	fmt.Println("f2", n)
}
func main() {
	//wg.Add(2)
	go f1()
	go f2()
	wg.Wait()
	fmt.Println("main:", n)
}

执行结果如下

image

把代码修改一下,即可


import (
	"fmt"
	"sync"
)

var n int
var wg sync.WaitGroup

func f1() {
	defer wg.Done()
	//wg.Add(1)
	for i := 0; i < 1000; i++ {
		n = n + 1
	}
	fmt.Println("f1", n)
}
func f2() {
	defer wg.Done()
	//wg.Add(1)
	for i := 0; i < 1000; i++ {
		n = n + 1
	}
	fmt.Println("f2", n)
}
func main() {
	wg.Add(2)
	go f1()
	go f2()
	wg.Wait()
	fmt.Println("main:", n)
}

执行结果如下

image

综上,Add()函数放到外面比较好,防止出现冲突。