Ответ
Буферизированный канал в Go — это канал, который имеет внутренний буфер для временного хранения данных. Он создается с указанием размера буфера: make(chan T, capacity)
.
Отправка данных (Send)
Когда горутина отправляет данные в буферизированный канал:
- Если в буфере есть свободное место, данные помещаются в буфер, и горутина-отправитель не блокируется, а сразу продолжает свою работу.
- Если буфер заполнен, горутина-отправитель блокируется до тех пор, пока другая горутина не прочитает данные из канала, освободив место в буфере.
Получение данных (Receive)
Когда горутина читает данные из буферизированного канала:
- Если в буфере есть данные, они немедленно извлекаются, и горутина-получатель не блокируется.
- Если буфер пуст, горутина-получатель блокируется до тех пор, пока в канал не будут отправлены новые данные.
// Канал с буфером на 2 элемента
ch := make(chan int, 2)
ch <- 1 // Не блокирует, место есть
ch <- 2 // Не блокирует, место есть
// Следующая отправка заблокирует горутину,
// так как буфер полон.
ch <- 3 // Блокировка!
Ключевые особенности:
- Асинхронность: Позволяет отправителю и получателю работать независимо, пока буфер не заполнится или не опустеет. Это помогает сглаживать пиковые нагрузки (например, когда отправитель работает быстрее получателя).
- Фиксированный размер: Размер буфера задается при создании и не может быть изменен.
- Чтение из закрытого канала: Если канал закрыт, можно прочитать все оставшиеся в буфере значения. После того как буфер опустеет, последующие чтения будут немедленно возвращать нулевое значение для типа канала и
false
в качестве второго возвращаемого значения (val, ok := <-ch
).