我正在尝试运行一些goroutine,并将它们的结果提供给一个通道。我需要一个好的方法,在所有goroutines完成后让通道关闭。
我第一次尝试是在产生所有goroutine后关闭它,但我认为在所有goroutine发送其结果之前,通道已经关闭了。
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...)
}
这个方法可以用,不过可能有更正确或者更有效的方式。而且,在一些情况下,如果后面的计数检查协程在循环中的协程之前运行,这种方法就无法工作。
是否有更好的方法?
wg.Wait(); close(c)
,但它给了我一个死锁错误。这是为什么? - A-letubbyc := make(chan any, 10)
,那么您就不会遇到这个错误,因为通道会在关闭和排空之前保留数据。 - Isaac Weingarten