Сколько обычно писателей и читателей бывает в канале в Go
Что проверяют
Не число, а понимание модели: знаете ли вы, что канал безопасен для любого количества отправителей и получателей, и кто в этой схеме отвечает за закрытие. Хороший ответ начинается с уточнения, а не с цифры.
Как отвечать
Обычного количества не существует, ограничений на число писателей и читателей у канала нет. Разговор идёт про схемы:
- один писатель и много читателей, это пул воркеров, раздача работы;
- много писателей и один читатель, это сбор результатов;
- один к одному, обычная передача владения данными между горутинами.
Дальше скажите главное правило: значение из канала получает ровно один читатель, а не все. Канал это не рассылка. Широковещание делается закрытием: после close все читатели разблокируются и получают нулевое значение с ok == false, поэтому закрытый канал и используют как сигнал отмены.
Закрывает канал отправитель, и только когда он остался один. При нескольких писателях закрытие превращается в гонку и панику send on closed channel, поэтому его выносят наружу:
var wg sync.WaitGroup
for i := 0; i < writers; i++ {
wg.Add(1)
go func() { defer wg.Done(); produce(ch) }()
}
go func() { wg.Wait(); close(ch) }()Размер буфера с числом писателей и читателей не связан: он сглаживает всплески, но схему не меняет.
Где спотыкаются
Говорят, что при нескольких читателях каждый получит своё значение. Получит один, а какой именно, планировщик не обещает. Нужно доставить всем, значит нужен либо канал на подписчика, либо закрытие как сигнал.
Закрывают канал со стороны читателя или из одной из горутин-писателей. Обе схемы дают панику. Читателю закрытие не нужно вовсе, ему хватает for range по каналу.
Считают буфер лекарством от блокировок. Если читатели медленнее писателей, буфер заполнится и писатели встанут ровно так же, только позже. Хуже того, буфер прячет отсутствие обратного давления, а при завершении процесса накопленные значения теряются.