У меня есть один канал, и приемник является основным. Я порождаю несколько goroutines, каждая из которых отправляет строку по каналу.
Теперь, это вызывает тупик, потому что я не закрыл канал должным образом, используя функцию закрытия. Дело в том, что я понятия не имею, сколько будет создано подпрограмм, поэтому нет способа узнать, когда закрывать канал.
Я пытался использовать WaitGroup, проблема в том, что я прочитал, что я не могу использовать Add в goroutine и что я должен использовать wg.Add (1) в основном процессе / goroutine, я пытался использование Add в родительском goroutine, порождающем дочерний goroutine, что также вызывает тупик
основной пакет
import (
"fmt"
"sync"
)
var i = 0
func doSomething(ch chan string, wg sync.WaitGroup) {
defer wg.Done()
ch <- fmt.Sprintf("doSomething: %d", i)
i++
if i == 10 {return}
wg.Add(1)
go doSomething(ch, wg)
}
func main() {
ch := make(chan string)
var wg sync.WaitGroup
wg.Add(1)
go doSomething(ch, wg)
wg.Wait()
for s := range ch {
fmt.Println(s)
}
}
Теперь, это всего лишь тестовый код, поэтому предположим, что мы не знаем, что мы создадим только 10 процедур, предположим, что он неизвестен во время выполнения, здесь я получаю тупиковую ошибку мгновенно без вывода, если я не не использую WorkGroup Я получаю сообщение об ошибке перед печатью 10-й строки (потому что я не закрывал канал)
Я также пытался не создавать goroutine для каждого вызова функции и вместо этого использовать одну goroutine для всех рекурсивных вызовов (начиная с main), и чтобы закрыть канал, я создал анонимную функцию для go, которая сначала вызывает doSomething Затем функция вызывает close, поэтому все рекурсивные вызовы будут оценены, и мы точно будем знать, когда закрывать канал. Но теперь это то, чего я пытаюсь достичь, я пытаюсь заставить неизвестное количество горутин работать вместе и закрыть канал после того, как они все как-то закончили.