duande9301 2014-02-17 02:14
浏览 28
已采纳

所有goroutine完成后,让golang关闭使用的频道

I am trying to run a number of goroutines which will give their results to a channel. I need a good way to let channel close after all goroutines are done.

My first try is to close it after spawn all go routines but I think somehow the channel is closed before all goroutines can send their results.

for i:=0; i<=10;i++{
  go func(){
    result:=calculate()
    c<-result
  }()
}
close(c)
for result:= range c{
  all_result=append(all_result, result...)
}

Then, my second try I come up with counting a thread and close it after no thread is running.

for i:=0; i<=10;i++{
  go func(){
    atomic.AddUint64(&go_routine_count, 1)
    result:=calculate()
    c<-result
    atomic.AddUint64(&rt_count, ^uint64(0))
  }()
}
go func(){
  for{
    // some little time to let above goroutine count up go_routine_count before this goroutine can actually check go_routine_count==0
    time.Sleep(time.Millisecond)
    go_current_routine_count:=atomic.LoadUint64(&go_routine_count)
    if go_routine_count==0{
      close(c)
    }
  }
}()
for result:= range c{
  all_result=append(all_result, result...)
}

It works but I feel there might be more correct or more efficient way. Also, somehow in some case if the later goroutine for count check is run before the goroutines in loop, this method won't work.

Is there a better way?

  • 写回答

1条回答 默认 最新

  • dongmi5020 2014-02-17 02:38
    关注

    The sync.WaitGroup type should encapsulate what you want to do, without needing sleep calls or busy waiting. It allows you to wait on an arbitrary number of tasks, not worrying about which order they complete.

    Taking your original example, you could alter it to use a wait group like so:

    var wg sync.WaitGroup
    for i:=0; i<=10;i++{
        wg.Add(1)
        go func(){
            result:=calculate()
            c<-result
            wg.Done()
        }()
    }
    // Close the channel when all goroutines are finished
    go func() {
        wg.Wait()
        close(c)
    }()
    for result:= range c{
        all_result=append(all_result, result...)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)