Гайды
Go: горутины и каналы
Планировщик и GOMAXPROCS, буферизованные каналы, select, sync и context, гонки и pprof.
~11 мин чтения
Go: горутины и каналы
Горутины — лёгкие потоки выполнения под управлением runtime Go; каналы (chan) передают данные и синхронизируют. Девиз: «Не общайтесь разделяя память; разделяйте память общаясь через каналы» — ориентир, не догма. Веб-сервисы на Go — Gin и Fiber.
1. Запуск горутины
go func() { fmt.Println("async") }()
Планировщик m:n мультиплексирует горутины на OS threads (GOMAXPROCS).
2. Каналы
ch := make(chan int, 2) // буфер 2
ch <- 1
v := <-ch
close(ch)
range по каналу до close. Закрывает только отправитель.
3. select
Мультиплексирование ожидания нескольких каналов + default для неблокирующего поведения.
// import "time"
select {
case msg := <-ch:
fmt.Println("received", msg)
case <-time.After(time.Second):
fmt.Println("timeout")
default:
fmt.Println("no message ready")
}
Типичный паттерн завершения: case <-ctx.Done(): return ctx.Err() рядом с рабочими каналами, чтобы горутина не зависла после отмены контекста.
4. sync примитивы
WaitGroup, Mutex, Once, context.Context для отмены и дедлайнов в цепочке вызовов.
5. Антипаттерны
- Гонки данных —
go test -race. - Утечка горутин на блокирующем send без получателя.
- Busy loop без
select/sleep.
6. Пул воркеров и errgroup
Фиксированное число горутин читает задания из канала-очереди — предсказуемая нагрузка на CPU и сокеты. Пакет golang.org/x/sync/errgroup связывает отмену и первую ошибку между подзадачами; передавайте context из группы вниз по вызовам.
7. Graceful shutdown
На SIGINT/SIGTERM закройте приём новых запросов, отмените context, дождитесь WaitGroup воркеров с таймаутом. Каналы завершения: закрыть входную очередь после дренажа или использовать context.Done() в select отправителей.
8. Чек-лист
- Явный context в публичных API.
- Пулы воркеров для CPU-bound вместо бесконечного
goна каждый байт. - Профилирование pprof под нагрузкой.
- Лимиты на буферы каналов и back-pressure при быстром продюсере.
-
GOMAXPROCSосознанно в контейнерах (CPU quota vs физические ядра).
Дальше: Gin и Fiber · тег Go