go并发编程之三(sync保持所有goroutine的完整执行WaitGroup)

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 := "[email protected]"
	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
[email protected] send a email success
done all the work

需要注意的是:go中所有的参数传递是值传递,而 WaitGroup 为了保持同步一致性,需要修改该结构体的值,所以我们使用 & 传递参数,并用 * 指针来接收,否则,会出现:

sync: negative WaitGroup counter

这种错误,究其根源,就是传值问题

猜你喜欢

转载自blog.csdn.net/wujiangwei567/article/details/86683993