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