Принцип работы небуферизированного канала в Go

Ответ

Небуферизированный канал в Go — это канал с нулевой емкостью (make(chan T)), который обеспечивает синхронный обмен данными между горутинами. Этот процесс также называют рандеву (rendezvous).

Принцип работы:

Отправка данных в такой канал (ch <- data) блокирует горутину-отправителя до тех пор, пока другая горутина не будет готова принять эти данные (data := <-ch). Аналогично, чтение из канала блокирует горутину-получателя, пока кто-то не отправит данные.

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: готов принять данные")
    val := <-ch // Блокировка, пока горутина не отправит данные
    fmt.Printf("Main: данные получены: %dn", val)
}

Ключевые аспекты:

  • Синхронизация (Рандеву): Операция завершается только тогда, когда и отправитель, и получатель готовы. Это мощный механизм для синхронизации горутин.
  • Гарантированная доставка: Отправитель может быть уверен, что сообщение было получено в момент разблокировки.
  • Риск дедлока (Deadlock): Если горутина отправляет данные в канал, но нет другой горутины, которая из него читает (или наоборот), программа зависнет в состоянии дедлока.