所有goroutines结束后让golang关闭使用的频道

前端之家收集整理的这篇文章主要介绍了所有goroutines结束后让golang关闭使用的频道前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试运行一些goroutines,它们会将结果发送到一个频道.在完成所有goroutine之后,我需要一个让通道关闭的好方法.

我的第一次尝试是在产生所有go例程后关闭它,但我认为在所有goroutine可以发送结果之前,某个频道已关闭.

  1. for i:=0; i<=10;i++{
  2. go func(){
  3. result:=calculate()
  4. c<-result
  5. }()
  6. }
  7. close(c)
  8. for result:= range c{
  9. all_result=append(all_result,result...)
  10. }

然后,我第二次尝试计算一个线程并在没有线程运行后关闭它.

  1. for i:=0; i<=10;i++{
  2. go func(){
  3. atomic.AddUint64(&go_routine_count,1)
  4. result:=calculate()
  5. c<-result
  6. atomic.AddUint64(&rt_count,^uint64(0))
  7. }()
  8. }
  9. go func(){
  10. for{
  11. // some little time to let above goroutine count up go_routine_count before this goroutine can actually check go_routine_count==0
  12. time.Sleep(time.Millisecond)
  13. go_current_routine_count:=atomic.LoadUint64(&go_routine_count)
  14. if go_routine_count==0{
  15. close(c)
  16. }
  17. }
  18. }()
  19. for result:= range c{
  20. all_result=append(all_result,result...)
  21. }

它有效,但我觉得可能有更正确或更有效的方式.此外,在某些情况下,如果后来的计数检查goroutine在循环中的goroutines之前运行,则此方法将不起作用.

有没有更好的办法?

sync.WaitGroup类型应该封装您想要做的事情,而不需要睡眠呼叫或忙碌等待.它允许您等待任意数量的任务,而不必担心它们完成的顺序.

以您的原始示例为例,您可以将其更改为使用等待组:

  1. var wg sync.WaitGroup
  2. for i:=0; i<=10;i++{
  3. wg.Add(1)
  4. go func(){
  5. result:=calculate()
  6. c<-result
  7. wg.Done()
  8. }()
  9. }
  10. // Close the channel when all goroutines are finished
  11. go func() {
  12. wg.Wait()
  13. close(c)
  14. }()
  15. for result:= range c{
  16. all_result=append(all_result,result...)
  17. }

猜你在找的Go相关文章