Блокирует ли чтение из пустого канала выполнение в Go?

Открытый, закрытый и nil-канал ведут себя по-разному. Блокируется горутина; select позволяет добавить отмену или неблокирующую ветку.

Короткий ответ

Что ответить на собеседовании

Чтение из открытого пустого канала ожидает отправку. Если закрытый канал уже опустошён, чтение немедленно вернёт нулевое значение и ok=false. Чтение из nil-канала блокируется навсегда. Обычно приостанавливается текущая горутина, а не весь поток ОС; другие горутины могут продолжать работу.

Подробный разбор

Ответ с пояснениями

Нужно уточнить состояние канала. Пустота буфера сама по себе не описывает все случаи:

  • Открытый канал без доступного значения: чтение ждёт отправителя.
  • Закрытый канал с буфером: сначала читаются сохранённые значения.
  • Закрытый и опустошённый канал: немедленно возвращаются нулевое значение типа и ok == false.
  • nil-канал: обычное чтение не завершается.

Пример закрытого канала:

ch := make(chan int, 1)
ch <- 42
close(ch)

value, ok := <-ch // 42, true
value, ok = <-ch  // 0, false
_ = value
_ = ok

Правила приведены в спецификации Go. Нулевое значение не доказывает закрытие: отправитель тоже может передать 0, поэтому используют форму с ok.

При ожидании канал приостанавливает текущую горутину; рантайм может выполнять другие горутины на доступных потоках. Это не остановка всей программы. Если все возможные участники ждут и никто не сможет отправить, программа может оказаться в deadlock.

В select можно предусмотреть ctx.Done() для отмены или default для неблокирующей попытки. Но цикл с постоянно выбираемым default способен бесполезно расходовать CPU.

Практика в реальном времени

Подготовьтесь к следующему собеседованию

Interview Boost учитывает вакансию, резюме и технологии и помогает сформулировать ответ прямо во время интервью.

Начать подготовку