Ответ
Небуферизированный канал в Go — это канал с нулевой емкостью (make(chan T)
), который обеспечивает синхронную передачу данных между горутинами.
Основная особенность заключается в том, что операция отправки и операция получения данных должны произойти одновременно. Это также называют «рандеву».
Принцип работы:
- Отправка (
ch <- data
) блокирует отправляющую горутину до тех пор, пока другая горутина не будет готова принять данные из этого же канала. - Получение (
<-ch
) блокирует принимающую горутину до тех пор, пока другая горутина не отправит данные в этот канал.
Таким образом, данные передаются напрямую от отправителя к получателю, без промежуточного хранения в канале. Это гарантирует, что в момент обмена обе горутины синхронизированы.
Пример:
package main
import (
"fmt"
"time"
)
func main() {
// Создаем небуферизированный канал
ch := make(chan string)
go func() {
fmt.Println("Горутина: готовлюсь отправить данные...")
ch <- "Привет от горутины!" // Блокируется здесь, пока main не будет готова принять
fmt.Println("Горутина: данные успешно отправлены.")
}()
fmt.Println("Main: жду 2 секунды перед получением...")
time.Sleep(2 * time.Second)
fmt.Println("Main: готовлюсь получить данные...")
value := <-ch // Разблокирует горутину-отправителя
fmt.Printf("Main: получил данные: '%s'n", value)
time.Sleep(1 * time.Second) // Даем время горутине завершиться
}
Ключевые моменты:
- Синхронизация: Идеально подходит для синхронизации горутин, когда нужно гарантировать, что одно действие произошло перед другим.
- Deadlock: Если горутина пытается отправить данные, но нет получателя (или наоборот), программа впадет в
deadlock
.