Согласно GOPL, «выбранный ждет, пока сообщение для некоторого случая не будет готово для продолжения», тогда что происходит с каналом, который не выбран? Кроме того, не застрянет ли горутина, которая отправляет сообщение на «невыбранный» канал, что вызовет утечку горутины?
Или из-за того, что «невыбранный» канал недоступен, он собирается сборщиком мусора (сразу?), а также собирается застрявшая горутина?
Невыбранные каналы останутся «нетронутыми». Точнее невыбранные операции связи выполняться не будут.
Вызывает ли это взаимоблокировку или утечку goroutine в вашем приложении, полностью зависит от вашего приложения. У вас может быть несколько горутин, отправляющих/получающих из этих каналов, и select
может находиться в цикле, многократно выполняя select
, в конечном итоге выполняя все готовые коммуникационные операции.
Каналы, как и все значения в Go, удаляются сборщиком мусора, когда они становятся недоступными, то есть никакой код Go не имеет на них «ссылки». Если горутина заблокирована при попытке отправки/получения из канала, это считается «имеющей ссылку» на канал, и поэтому сборщик мусора не может «спасти» этот канал.
Сборщик мусора — это не инструмент для решения ваших тупиковых ситуаций, а для освобождения недоступной, неиспользуемой памяти. Вы должны думать о решении взаимоблокировок.
Горутины не «собираются» (завершаются и их ресурсы освобождаются) до тех пор, пока функция, которую они выполняют, не завершает свое выполнение или не паникует и не приводит к сбою процесса. Помните, что операции по отправке канала также являются допустимым случаем
select
, поэтому вы можете попытаться отправить по каналу, но затем истечете время ожидания и сделаете что-то еще (например, завершите горутину), если отправка не будет успешной в течение установленного периода времени.