Буферизованный канал имеет внутреннюю очередь. Отправка не блокирует, пока буфер не заполнен.
ch := make(chan int, 3) // буфер на 3 элемента
ch <- 1 // не блокирует
ch <- 2 // не блокирует
ch <- 3 // не блокирует
ch <- 4 // БЛОКИРУЕТ — буфер полон
fmt.Println(len(ch)) // 3 (сколько элементов сейчас)
fmt.Println(cap(ch)) // 3 (размер буфера)
Когда использовать:
- Небуферизованный (
make(chan T)) — синхронизация, «передача из рук в руки» - Буферизованный — развязка скоростей producer/consumer, batch-обработка
sem := make(chan struct{}, 10) // макс 10 параллельных
for _, url := range urls {
sem <- struct{}{} // займи слот
go func(u string) {
defer func() { <-sem }() // освободи слот
fetch(u)
}(url)
}