Я думаю, вы зашли в тупик, потому что ваш func2
потребляет только 1 значение из ch
и затем завершает работу. Затем другие func1
goroutines застряли в ожидании готовности ch
для записи, что они не могут сделать, потому что нет другой goroutine для чтения из ch
на другом конце.
Так как вы Чтобы func2
непрерывно принимал значения от ch
до закрытия ch
, вам нужно создать al oop в func2
примерно так:
func func2(ch chan int) {
fmt.Println("func2")
for v := range ch {
fmt.Println(v)
}
}
Это сохранит func2
" живы "и читают с ch
до тех пор, пока вы не сделаете close(ch)
где-то еще. Подходящее место для закрытия ch
в вашем примере, вероятно, будет в main
после wg.Wait()
.
Если вы хотите быть уверенным, что увидите результаты всех операторов Println
до завершения программы, Вы также должны использовать некоторый механизм синхронизации, чтобы дождаться окончания func2
до sh. В противном случае main
закончится сразу после close(ch)
, которое может или не может быть до того, как func2
напечатает каждое полученное значение.
Обычный метод для этого - "выполнено" канал. Например:
func func2(ch chan int, done chan bool) {
fmt.Println("func2")
for v := range ch {
fmt.Println(v)
}
done <- true
}
и main
:
done := make(chan bool)
go func2(ch, done)
...
wg.Wait()
close(ch)
<-done
Использование chan struct{}
(пустая структура) также очень распространено, поскольку пустая структура не требует памяти.