[英]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.