Кто закрывает каналы пула
В пуле появился канал результатов, и воркеры встали на его отправке. Аня снова подняла спор, кто закрывает канал задач: один закрывал производитель, другой — горутина, дождавшаяся всех воркеров.
в пуле с результатами два канала и два владельца закрытия: 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
Проверьте себя
Воркер закрыл общий канал results сам, как только закончил. Что будет с несколькими воркерами?
Закрывающую горутину убрали, а main читает results через range. Что произойдёт?
Как сохранить порядок результатов в пуле с results-каналом?
правильных ответов
Два канала — два владельца: tasks закрывает производитель, results — горутина после wg.Wait. Забытый владелец = тупик или паника.
10 000 ₽ · 60 минут · онлайн