Go语言学习之Go协程:WaitGroup
2021-03-21 19:24
标签:var exiting text wait Go语言 defer warning 通信 for 我们之前学习了协程和信道,里面有很多例子,当时为了保证main goroutine在所有的goroutine都执行完毕后在退出,我们使用了time.Sleep这种方式 由于写的demo都是很简单的,sleep个1秒,我们感觉应该是够用的 但是在实际开发中,我们无法预知,所有的goroutine需要多长时间才能执行完毕,sleep多了 主程序就会阻塞,sleep少了有的子协程的任务无法完成 我们今天来介绍一下 怎么优雅的处理这种情况 1.使用信道来标记完成 信道可以实现多个协程间的通信,那么我们只需要定义一个信道,在任务完成后,往信道中写入true,然后主协程中获取到true,就认为子协程执行完毕 输出如下 2.使用WaitGroup 上面使用的方法,在单个协程或者协程数量比较少的时候不会有什么问题,但在协程数多的时候,代码就会很复杂 更优雅的方式就是使用WaitGroup WaitGroup只要实例化了就能用 实例化完成后,就可以使用它的几个方法: Add:初始值为0,你传入的值会往计数器上加,这里直接传入子协程的数量 Done: 当某个子协程完成后,可以调用此方法,就会从计数器上减1,通常可以使用defer来调用 Wait: 阻塞当前协程,知道计数器的值归0 举一个例子 上面使用信道的方法,在单个协程或者协程数少的时候,并不会有什么问题,但在协程数多的时候,代码就会显得非常复杂 Go语言学习之Go协程:WaitGroup 标签:var exiting text wait Go语言 defer warning 通信 for 原文地址:https://www.cnblogs.com/chadiandianwenrou/p/13886572.htmlimport "fmt"
func main() {
done := make(chan bool)
//开一个协程去执行
go func() {
for i := 0; i 5; i++ {
fmt.Println(i)
}
//执行完毕,往信道里写入true
done true
}()
//主协程中如果获取到信道里时true 就退出
done
}
0
1
2
3
4
var 实例名 sync.WaitGroup
// Startup the EventRouter
//这里有一个协程, 所以计数器的值是1
wg.Add(1)
//协程
go func() {
//defer的作用是在eventRouter.run函数执行完,在执行defer的语句,所以这里就是程序执行完了,执行wg.Done()把计数器里的值减1
defer wg.Done()
eventRouter.Run(stop)
}()
// Startup the Informer(s)
glog.Infof("Starting shared Informer(s)")
sharedInformers.Start(stop)
//主协程一直调用wg.Wait()方法阻塞着,直到计数器的值为0在执行后面的代码
wg.Wait()
//执行这个代码的时候,说明计数器归0了,wg.Wait失效,不会阻塞主协程了
glog.Warningf("Exiting main()")
os.Exit(1)