Ответ
Буферизированный канал создается с указанием размера буфера: make(chan T, capacity)
, где capacity > 0
.
Поведение при записи в такой канал зависит от того, заполнен ли его буфер:
Если в буфере есть место:
Запись происходит немедленно и не блокирует горутину. Значение помещается в очередь внутри канала, и горутина продолжает свое выполнение.Если буфер заполнен:
Запись блокирует текущую горутину. Она будет ждать до тех пор, пока другая горутина не прочитает данные из канала, освободив тем самым место в буфере.
Пример:
package main
import "fmt"
func main() {
// Канал с буфером на 2 элемента
ch := make(chan int, 2)
fmt.Println("Отправляем 1...")
ch <- 1 // Не блокируется, буфер: [1]
fmt.Println("Отправляем 2...")
ch <- 2 // Не блокируется, буфер: [1, 2]
fmt.Println("Буфер полон. Отправляем 3...")
// Следующая строка вызовет deadlock, так как буфер полон,
// а читающей горутины нет. Программа заблокируется навсегда.
ch <- 3 // Блокируется
fmt.Println("Эта строка никогда не будет выполнена")
}
Ключевой момент: Буферизация позволяет горутинам-отправителям и горутинам-читателям работать асинхронно до тех пор, пока буфер не заполнится или не опустеет. Это может значительно повысить производительность, снижая количество блокировок.