Ответ
Небуферизированный канал в Go — это канал с нулевой емкостью, создаваемый как make(chan T)
. Его главная особенность — синхронизация горутин.
Принцип работы (рандеву):
- Отправка в такой канал (
ch <- data
) блокирует горутину-отправителя до тех пор, пока другая горутина не будет готова принять данные из этого же канала. - Чтение из канала (
<-ch
) блокирует горутину-получателя до тех пор, пока другая горутина не отправит данные в этот канал.
Это создает точку синхронизации, или "рандеву", где отправитель и получатель должны встретиться для совершения обмена.
Пример:
// Создаем небуферизированный канал
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)
Ключевые особенности и использование:
- Гарантия доставки: Отправка завершается только тогда, когда данные приняты.
- Синхронизация: Идеально подходит для сигнализации о завершении работы или для координации действий между горутинами без использования мьютексов.
- Прямая передача: Данные передаются напрямую от отправителя к получателю без промежуточного хранения.
В отличие от буферизированного канала, который позволяет отправителю продолжить работу, если в буфере есть место, небуферизированный требует немедленной встречи получателя.