WaitGroup
的使用说明
1. WaitGroup的定义
WaitGroup
定义了三个函数,分别是
Add
: 添加任务
Done
: 任务完成
Wait
: 等待任务完成
通过这三个函数,我们可以安全等待多个异步的goutine的执行完成,示意图如下
2. WaitGroup的使用
举个栗子,比如我们同时调用了两个goroutine帮我们执行发邮件和写日志的操作,但是我们无法得知这两个任务是否已经完成了,这时我们就可以用到
WaitGroup
,直接上代码
package main
import (
"fmt"
"sync"
"time"
)
func sendEmail(email string ,group *sync.WaitGroup) {
//这里做了一系列耗时的操作
time.Sleep(3*time.Second)
fmt.Println(email, "send a email success ")
defer group.Done()
}
func writeLog(log string ,group *sync.WaitGroup){
//假设这里做了一系列写日志操作
time.Sleep(2*time.Second)
fmt.Println( log," success ")
defer group.Done()
}
func main() {
var waitGroup sync.WaitGroup
email := "123@126.com"
log := "oper email "
waitGroup.Add(2)
go sendEmail(email ,&waitGroup)
go writeLog(log ,&waitGroup)
waitGroup.Wait()
fmt.Println("done all the work ")
}
打印结果:
oper email success
123@126.com send a email success
done all the work
需要注意的是:go中所有的参数传递是值传递,而
WaitGroup
为了保持同步一致性,需要修改该结构体的值,所以我们使用&
传递参数,并用*
指针来接收,否则,会出现:
sync: negative WaitGroup counter
这种错误,究其根源,就是传值问题