Ответ
Небуферизированный канал (или синхронный канал) — это канал с нулевой емкостью, создаваемый как make(chan T)
. Он используется для прямой синхронизации между горутинами.
Механизм "Рандеву"
Передача данных через небуферизированный канал — это синхронная операция, требующая одновременного участия и отправителя, и получателя. Этот механизм называется "рандеву" (rendezvous).
- Отправка: Горутина, отправляющая данные (
ch <- data
), блокируется и ждет, пока другая горутина не будет готова принять эти данные. - Получение: Горутина, читающая данные (
data := <-ch
), блокируется и ждет, пока другая горутина не отправит данные в этот канал.
Передача данных происходит только тогда, когда и отправитель, и получатель готовы. В этот момент значение копируется напрямую от отправителя к получателю, после чего обе горутины разблокируются и продолжают выполнение.
// Небуферизированный канал
ch := make(chan int)
go func() {
// Горутина блокируется здесь, пока main не будет готова читать
ch <- 42
}()
// main горутина блокируется здесь, пока другая горутина не отправит данные
val := <-ch // Происходит "рандеву", обе горутины разблокируются
fmt.Println(val) // 42
Ключевые особенности:
- Гарантия доставки: Отправитель может быть уверен, что сообщение было получено, как только его операция отправки завершилась.
- Синхронизация: Это мощный примитив для синхронизации выполнения двух горутин в определенной точке.
- Отсутствие буфера: Канал не хранит значения, он лишь служит точкой для их прямой передачи.