Ответ
Небуферизированный канал в 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): Если горутина отправляет данные в канал, но нет другой горутины, которая из него читает (или наоборот), программа зависнет в состоянии дедлока.