go 怎么等待所有的协程完成_优雅地等待子协程执行完毕

goroutine模拟了线程级别的返场的能力,但它的执行需要主协程给机会。一般的作法用sleep,chan阻塞,看起来让人不爽,本文介绍sync.WaitGroup 类型结合 defer 的特性,给出优雅的解决方案。

缘起

下面这段代码众所周知不会打招呼

....

func main(){

go sayHi(){

fmt.Println("say hello......")

}()

fmt.Println("main groutine....")

}

等待

上述代码不会讲hello,在于主协程main无等待(阻塞),子协程sayHi没有露脸的机会。

为了让子协程sayHai上场,通常在主协程末了加这么一句,让它睡会儿

time.Sleep(1e9)

但想想不科学,如果子协程在它睡期间,没能完成任务,超时了,子协程仍然打不了招呼。又或者子协程完成了,主协程还在睡,岂不是主线程不作为?睡的时间多久怎样才合理...

通道

用通道可解决阻塞时间合理性质疑。

若启用了多个子协程,可以这样实现主协程等待子协程执行完毕并退出的:声明一个和子协程数量一致的通道数组,然后为每个子协程分配一个通道元素,在子协程执行完毕时向对应的通道发送数据;然后在主协程中,依次读取这些通道接收子协程发送的数据,只有所有通道都接收到数据才会退出主协程。

代码看起来像这样

chs := make([]chan in

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值