• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Go语言学习之Go协程:WaitGroup

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

我们之前学习了协程和信道,里面有很多例子,当时为了保证main goroutine在所有的goroutine都执行完毕后在退出,我们使用了time.Sleep这种方式

由于写的demo都是很简单的,sleep个1秒,我们感觉应该是够用的

但是在实际开发中,我们无法预知,所有的goroutine需要多长时间才能执行完毕,sleep多了 主程序就会阻塞,sleep少了有的子协程的任务无法完成

我们今天来介绍一下 怎么优雅的处理这种情况

1.使用信道来标记完成

信道可以实现多个协程间的通信,那么我们只需要定义一个信道,在任务完成后,往信道中写入true,然后主协程中获取到true,就认为子协程执行完毕

import "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

2.使用WaitGroup

上面使用的方法,在单个协程或者协程数量比较少的时候不会有什么问题,但在协程数多的时候,代码就会很复杂

更优雅的方式就是使用WaitGroup

WaitGroup只要实例化了就能用

var 实例名 sync.WaitGroup 

实例化完成后,就可以使用它的几个方法:

  1. Add:初始值为0,你传入的值会往计数器上加,这里直接传入子协程的数量
  2. Done: 当某个子协程完成后,可以调用此方法,就会从计数器上减1,通常可以使用defer来调用
  3. Wait: 阻塞当前协程,知道计数器的值归0

举一个例子

// 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)

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go基本IO接口发布时间:2022-07-10
下一篇:
下个10年,Go能取代Python成为开发者的首选语言吗?发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap