1. Первый вопрос: паника
Если я закрываю канал, я получаю сообщение об ошибке: "panic: send on closed channel"
Почему? Один из вас пытается запрограммировать запись на канал, который вы уже закрыли в вызывающей (основной) программе. В вашем случае в функции WordCount
.
В текущей версии вашего кода panic
не воспроизводится с моим тестовым предложением, но вы можете легко вызвать это, например. если бы вы позвонили close(wordChannel)
до wg.Wait()
.
Давайте посмотрим на Ошибка в processToCounting
, которая может вызвать panic
:
wg.Done() // tells to the WaitGroup that the gouroutine is Done (decrements the counter of goroutines)
wordChannel <- freq // trying to write to the channel
Здесь wg.Done()
сигнализирует WaitGroup
о том, что программа составляет Done
до того, как произойдет фактическая запись в канал. Вызывающая программа (функция WordCount
) в какой-то момент считает, что все гурутины выполнены (строка wg.Wait()
) и закрывает канал. Но одна из ваших подпрограмм, которая еще не закончила писать, попытается написать на закрытый канал. Тогда вы получите panic
.
Как исправить:
Использование defer
в processToCounting
функция
defer wg.Done() // triggers wg.Done right before the function returns (but after writing to the channel in your case)
Что читать:
Смотрите для начинающих в Тур по Го / Параллелизм
Отправка по закрытому каналу вызовет панику.
и документация для: close
Отправка или закрытие закрытого канала вызывает панику во время выполнения.
2. Второй вопрос: тупик
Если я не закрываю канал, я получаю: «фатальная ошибка: все программы спят - тупик!»
У вас есть цикл for, который читает канал. Эта петля for заблокирована навсегда. В ожидании новых значений из канала, но никто больше не напишет туда.
См. Тур по Го / Параллелизм
Цикл для диапазона i: = c многократно принимает значения от канала до его закрытия.
и см. Документацию по Каналам
Приемники всегда блокируются, пока нет данных для приема