Пусть golang закрытия канала после все горутины закончил
Я пытаюсь запустить несколько goroutines, которые дадут свои результаты каналу. Мне нужен хороший способ закрыть канал после того, как все горотины будут сделаны.
Моя первая попытка-закрыть его после того, как все процедуры spawn all go, но я думаю, что каким-то образом канал закрывается до того, как все 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 для count выполняется перед goroutines в цикле, этот метод не будет работать.
Есть ли лучший способ?
1 ответ:
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...) }