Каков размер буфера у небуферизированного канала в Go и как это влияет на его поведение?

Ответ

У небуферизированного канала (make(chan T)) размер буфера равен нулю (0).

Это означает, что канал не может хранить в себе значения. Любая операция записи или чтения является синхронной и блокирующей:

  • Отправка (ch <- data) блокирует текущую горутину до тех пор, пока другая горутина не будет готова прочитать данные из этого канала.
  • Чтение (<-ch) блокирует текущую горутину до тех пор, пока другая горутина не отправит данные в этот канал.

Такое поведение обеспечивает точку синхронизации между горутинами, известную как "рандеву" (rendezvous).

Пример:

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int) // Небуферизированный канал

    go func() {
        fmt.Println("Горутина: отправляю данные...")
        ch <- 42 // Эта операция заблокируется, пока main не прочитает
        fmt.Println("Горутина: данные отправлены!")
    }()

    time.Sleep(1 * time.Second) // Даем время горутине дойти до отправки
    fmt.Println("Main: готовлюсь читать данные...")
    value := <-ch // Чтение разблокирует горутину-отправителя
    fmt.Printf("Main: получил значение %dn", value)
}