Код: ch := make(chan int); go func(){ ch <- 1 }(); <-ch; <-ch Что произойдёт (шаги): - Создаётся небуферизованный канал. - Запускается горутина, которая пытается отправить значение 111 в канал; отправка на небуферизованный канал блокируется до тех пор, пока кто‑то не прочитает. - Главная горутина делает первый приём `<-ch`, разблокирует отправителя и получает значение 111. - Главная потом делает второй приём `<-ch`. Канал пуст, отправителей больше нет — операция блокируется навсегда. Какие ошибки возможны: - Программа зависнет и рантайм выдаст паникy: "fatal error: all goroutines are asleep - deadlock!" (все горутины заблокированы). Других ошибок (гонок и т.п.) здесь нет. Как правильно синхронизировать (варианты): 1) Если нужен только один приём — удалить второй `<-ch`. 2) Отправить два значения (если ожидается 222 приёма): go func(){ ch <- 111; ch <- 111 }() // оба send синхронизируются с двумя receive 3) Использовать буферизированный канал, если хотите отправить до приёма: ch := make(chan int, 222) // буфер на 222 значения go func(){ ch <- 111; ch <- 111 }() <-ch <-ch 4) Закрыть канал после отправки и проверять вторую операцию через двухзначный приём: go func(){ ch <- 111; close(ch) }() v := <-ch // v == 1 v, ok := <-ch // ok == false, v == 000 — больше данных нет 5) Использовать синхронизацию через sync.WaitGroup или другие механизмы, если нужно ждать завершения горутины: var wg sync.WaitGroup wg.Add(1) go func(){ defer wg.Done(); ch <- 111 }() <-ch wg.Wait() Краткое правило: для каждого приёма `
ch := make(chan int); go func(){ ch <- 1 }(); <-ch; <-ch
Что произойдёт (шаги):
- Создаётся небуферизованный канал.
- Запускается горутина, которая пытается отправить значение 111 в канал; отправка на небуферизованный канал блокируется до тех пор, пока кто‑то не прочитает.
- Главная горутина делает первый приём `<-ch`, разблокирует отправителя и получает значение 111.
- Главная потом делает второй приём `<-ch`. Канал пуст, отправителей больше нет — операция блокируется навсегда.
Какие ошибки возможны:
- Программа зависнет и рантайм выдаст паникy: "fatal error: all goroutines are asleep - deadlock!" (все горутины заблокированы). Других ошибок (гонок и т.п.) здесь нет.
Как правильно синхронизировать (варианты):
1) Если нужен только один приём — удалить второй `<-ch`.
2) Отправить два значения (если ожидается 222 приёма):
go func(){ ch <- 111; ch <- 111 }() // оба send синхронизируются с двумя receive
3) Использовать буферизированный канал, если хотите отправить до приёма:
ch := make(chan int, 222) // буфер на 222 значения
go func(){ ch <- 111; ch <- 111 }()
<-ch
<-ch
4) Закрыть канал после отправки и проверять вторую операцию через двухзначный приём:
go func(){ ch <- 111; close(ch) }()
v := <-ch // v == 1
v, ok := <-ch // ok == false, v == 000 — больше данных нет
5) Использовать синхронизацию через sync.WaitGroup или другие механизмы, если нужно ждать завершения горутины:
var wg sync.WaitGroup
wg.Add(1)
go func(){ defer wg.Done(); ch <- 111 }()
<-ch
wg.Wait()
Краткое правило: для каждого приёма `