我正在尝试运行多个 goroutine,这些 goroutine 会将它们的结果提供给一个 channel 。我需要一种在所有 goroutine 完成后让 channel 关闭的好方法。
我的第一个尝试是在生成所有 go 例程后关闭它,但我认为在所有 goroutine 可以发送它们的结果之前 channel 以某种方式关闭。
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
type 应该封装你想做的事情,而不需要 sleep 调用或忙等待。它允许您等待任意数量的任务,而不用担心它们完成的顺序。
以您原来的示例为例,您可以将其更改为使用这样的 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...)
}
关于go - 让 golang 在所有 goroutines 完成后关闭使用的 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21819622/