Все темы
Тема 01

Каналы и select

Разберись в теме, затем проверь понимание на задачах.

0/4 решено0%
К задачам

О чём этот блок

Четыре задачи блока — четыре ситуации, которые встречаются в любом сервисе. Горутина отдаёт результат, а получатель уже ушёл по таймауту. Генератор должен остановиться сам, если его никто не читает. Срочные сообщения нужно обрабатывать раньше обычных. Несколько сигналов отмены нужно свести в один.

Все четыре решаются каналами и select, и во всех главная ошибка одна: горутина, которая осталась ждать навсегда. Поэтому в каждой задаче, кроме «работает ли», задавайте себе вопрос «кто и когда остановит каждую запущенную горутину».

Что понадобится

  • Небуферизованный канал как точка встречи и буфер как запас места: когда отправка ждёт, а когда нет.
  • Закрытие канала как сигнал, который видят все получатели сразу (done-канал).
  • select с несколькими ветками, default для неблокирующей попытки и случайный выбор среди готовых веток.
  • nil-канал как способ выключить ветку select.
  • time.Timer и time.After для таймаутов.

Задачи и порядок решения

Решайте в порядке 02 → 03 → 04 → 01: от одной утечки к рекурсивной композиции.

  • 02 · Unbuffered канал и утечка горутины — продюсер висит на ch <- i, когда потребитель ушёл. Нужно дать ему второй выход через done-канал в select.
  • 03 · Generator с таймаутом бездействия — генератор закрывает канал сам, если из него 500 мс никто не читает. Таймер сбрасывается только после успешной отправки.
  • 04 · Очередь с приоритетом на select — сначала неблокирующая попытка прочитать high, потом ожидание обоих каналов; выход, когда закрыты оба. Это предпочтение, а не строгий приоритет: при постоянно готовом high канал low может голодать.
  • 01 · Or-Channel — один канал, который закрывается, когда сработал любой из N входных. Понадобится рекурсия и способ завершить все вспомогательные горутины.

Что прочитать

  • Каналы — буфер, закрытие, nil-канал, направления.
  • select — правила выбора, default, таймауты, таймеры в Go 1.23+, разбор рекурсии перед задачей 01.
  • Горутины и планировщик — почему зависшая горутина держит память.
// Идиома блока: отправить или сдаться по сигналу отмены, но не висеть.
select {
case out <- v:   // получатель забрал значение
case <-done:     // нас отменили: выходим
    return
}

Задачи темы 4