簡體   English   中英

在所有 goroutine 完成后讓 golang 關閉使用的通道

[英]Let golang close used channel after all goroutines finished

我正在嘗試運行一些 goroutines,它們會將它們的結果提供給一個通道。 在所有 goroutine 完成后,我需要一種讓通道關閉的好方法。

我的第一次嘗試是在生成所有 goroutines 后關閉它,但我認為通道在所有 goroutines 發送結果之前以某種方式關閉。

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

然后,我第二次嘗試計算一個線程並在沒有線程運行后關閉它。

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...)
}

它有效,但我覺得可能有更正確或更有效的方法。 此外,在某些情況下,如果后面的用於計數檢查的 goroutine 在循環中的 goroutines 之前運行,則此方法將不起作用。

有沒有更好的辦法?

sync.WaitGroup類型應該封裝您想要做的事情,而不需要睡眠呼叫或忙等待。 它允許您等待任意數量的任務,而不用擔心它們以什么順序完成。

以您的原始示例為例,您可以將其更改為使用等待組,如下所示:

    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...)
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM