Я пытаюсь решить эту проблему на Exercism:Проблемы с goroutines в цикле
Write a program that counts the frequency of letters in texts using parallel computation.
В принципе, у меня есть тип FreqMap
:
type FreqMap map[rune]int
И в Frequency
функции:
func Frequency(s string) FreqMap {
m := make(FreqMap)
for _, v := range s {
m[v]++
}
return m
}
Exercism представляет собой пример реализации параллельной версии используя рекурсию, но я хотел бы реализовать свою собственную версию, используя цикл for
. Я придумал следующее решение, которое не работает:
func ConcurrentFrequency(l []string) FreqMap {
c := make(chan FreqMap)
for i := 0; i < len(l); i++ {
go func(i int) {
c <- Frequency(l[i])
}(i)
}
return <- c
}
Это, кажется, вернуться только после 1 итерации, c
, кажется, содержит результат только 1 goroutine; Я получаю тот же результат, если добавлю sync.WaitGroup
.
Не могли бы вы объяснить, что мне здесь не хватает?
Заранее благодарю вас за помощь!
Большое спасибо, это, похоже, действительно решает мою проблему! Не могли бы вы объяснить мне, почему нам нужен первый goroutine, который завершает цикл 'for'? Если я удалю его, произойдет «фатальная ошибка: все горуты спали - тупик!», Но я не вижу причины. Еще раз спасибо! –
Не знаете, как вы изменили код, но я хочу, чтобы он зависел от wg.Wait - цикл потребления не будет достигнут тогда, поскольку код будет застрял там. Я использовал WaitGroup, чтобы канал можно было закрыть, когда все вызовы 'Frequency' возвращаются. Это обычный шаблон, когда вы возвращаете канал. – ain
Итак, если закрытие goroutine первого уровня, 'wg.Wait()' тайм-ауты остальное? Мой недостаток заключается в том, что 'wg.Done()' уменьшает счетчик WaitGroup, как только закрытие goroutine в 'for'loop возвращается; то почему существует тупик, когда 'wg.Wait() 'находится на уровне' ConcurrentFrequency() ', а не в вложенном goroutine? Извините, что беспокою вас еще раз, просто пытаясь понять большую часть этого, и ваши отзывы очень ценятся! –