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 51寻迹小车定点寻迹
  • ¥15 关于vue2中methods使用call修改this指向的问题
  • ¥15 idea自动补全键位冲突
  • ¥15 请教一下写代码,代码好难
  • ¥15 iis10中如何阻止别人网站重定向到我的网站
  • ¥15 滑块验证码移动速度不一致问题
  • ¥15 Utunbu中vscode下cern root工作台中写的程序root的头文件无法包含
  • ¥15 麒麟V10桌面版SP1如何配置bonding
  • ¥15 Marscode IDE 如何预览新建的 HTML 文件
  • ¥15 K8S部署二进制集群过程中calico一直报错