Материал проходит вычитку — возможны неточности.
Урок 115 из 118

Кто закрывает каналы пула

В пуле появился канал результатов, и воркеры встали на его отправке. Аня снова подняла спор, кто закрывает канал задач: один закрывал производитель, другой — горутина, дождавшаяся всех воркеров.

Главная мысль

в пуле с результатами два канала и два владельца закрытия: tasks закрывает производитель, results — горутина, ждущая воркеров через WaitGroup.

Пул с результатами

func processAll(items []int, workers int) []int {
    tasks := make(chan int)
    results := make(chan int)

    var wg sync.WaitGroup
    for i := 0; i < workers; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            for t := range tasks {
                results <- t * 2
            }
        }()
    }

    go func() {
        wg.Wait()
        close(results)
    }()

    go func() {
        for _, item := range items {
            tasks <- item
        }
        close(tasks)
    }()

    var out []int
    for r := range results {
        out = append(out, r)
    }
    return out
}

Два владельца закрытия

  • tasks закрывает производитель — он единственный, кто знает, когда задачи кончились.
  • results закрывает отдельная горутина после wg.Wait — воркеры закончили, отправлять больше некому.

Если воркер закроет results сам, другой воркер отправит в закрытый канал — паника. Разделение «кто закрывает» — тот самый вопрос из, применённый к пулу.

Тупик при неправильном закрытии

Частая ошибка — забыть закрывающую горутину: воркеры успешно отправят результаты, но читающий range results в главной горутине прочитает их и зависнет навсегда — канал никто не закроет. Другой тупик — если results вообще никто не читает: воркеры заблокируются на отправке. Порядок важен: закрывающая горутина запускается до того, как кто-то начнёт ждать результатов.

В следующем уроке

Вы узнаете:

  • как сохранить порядок результатов через индексы
  • почему закрывающую горутину запускают до чтения results
Задание · вопросы

Проверьте себя

Вопрос 1 из 3

Воркер закрыл общий канал results сам, как только закончил. Что будет с несколькими воркерами?

Вопрос 2 из 3

Закрывающую горутину убрали, а main читает results через range. Что произойдёт?

Вопрос 3 из 3

Как сохранить порядок результатов в пуле с results-каналом?

Итоги

Два канала — два владельца: tasks закрывает производитель, results — горутина после wg.Wait. Забытый владелец = тупик или паника.

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки