Материал проходит вычитку — возможны неточности.
Урок 77 из 118

Канал-рандеву

Сергей поручил Мише конвейер загрузки — цепочку шагов, где один принимает файл, другой разбирает, третий сохраняет. Миша собрал первый набросок: каждый шаг передавал результат следующему, и цепочка впервые заработала целиком. Это была первая система, которую он не просто писал, а проектировал.

Главная мысль

небуферизованный канал — это рандеву: отправка блокируется, пока другая горутина не примет значение, поэтому сам факт приёма — синхронизация.

Отправка и приём встречаются

next := make(chan File)

go func() { // следующий шаг конвейера
    f := <-next // заблокируется, пока предыдущий шаг не отдаст файл
    save(f)
}()

next <- file // разблокирует приём

Канал создаётся через make(chan T). Отправка ch <- v и приём <-ch — парные операции: небуферизованный канал передаёт значение только в момент, когда обе стороны готовы. Отправитель ждёт получателя, получатель ждёт отправителя — отсюда и «рандеву». Шаг конвейера не «кладёт» работу следующему, а передаёт её из рук в руки.

Отправка блокируется до приёма

ch := make(chan int)
ch <- 1 // заблокируется навсегда: принимать некому
fmt.Println("не дойдёт")

Отправка в небуферизованный канал без готового получателя — вечная блокировка (вспомни утечки горутин,). Это не ошибка: канал — инструмент синхронизации, и «ждать» — его работа.

Канал как сигнал

Самое чистое применение небуферизованного канала — сигнал «шаг завершился»:

done := make(chan struct{})

go func() {
    processFiles()
    close(done) // или done <- struct{}{}
}()

<-done // ждём завершения шага

struct{} — тип нулевого размера для сигналов: пустое значение, никаких данных. Закрытие канала — отдельный приём, но уже здесь видно: канал — это и передача данных, и синхронизация в одном инструменте.

В следующем уроке

Вы узнаете:

  • как happens-before работает у небуферизованного канала
  • как работают направленные каналы
<!-- wp:course-hub/quiz {"title":"Проверьте себя","questions":[{"text":"Что такое небуферизованный канал?","options":[{"text":"Рандеву — передача значения только в момент, когда обе стороны готовы","correct":true,"comment":"Отправитель ждёт получателя, получатель ждёт отправителя."},{"text":"Очередь фиксированной длины","correct":false},{"text":"Канал без синхронизации","correct":false},{"text":"Поток данных в одну сторону","correct":false}]},{"text":"ch := make(chan int); ch
Итоги

Небуферизованный канал — рандеву: передача в момент встречи. Отправка без получателя блокирует. Канал — и данные, и синхронизация.

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки