Горутины
Тема дорожной карты · Golang
Goroutines — фундаментальная единица конкурентности в Go: лёгкие кооперативно планируемые потоки выполнения, управляемые рантаймом Go, а не операционной системой. Запустить goroutine так же просто, как поставить ключевое слово go перед любым вызовом функции (go processRequest(req)); каждая goroutine начинает со стека всего в несколько килобайт, который динамически растёт и уменьшается, поэтому Golang-процесс может выполнять сотни тысяч goroutines на одной машине без исчерпания памяти. Goroutines взаимодействуют через каналы (make(chan T)) и синхронизируются с помощью примитивов пакета sync — sync.WaitGroup для ожидания группы goroutines, sync.Mutex и sync.RWMutex для защиты разделяемого состояния, sync.Once для одноразовой инициализации. M:N-планировщик рантайма Go мультиплексирует goroutines на потоки ОС (управляемые через GOMAXPROCS, по умолчанию равное числу ядер CPU), а goroutines автоматически вытесняются при операциях с каналами, операторах select, time.Sleep и системных вызовах, обеспечивая эффективное использование CPU без явных точек передачи управления. Обнаружение гонок данных между goroutines осуществляется встроенным race detector (go test -race ./... или go run -race main.go), что необходимо для обеспечения корректности конкурентных Golang-сервисов, развёртываемых в Kubernetes или работающих как gRPC-серверы.
Как это работает
Горутины построен на goroutines (лёгкие green threads, мультиплексируемые на OS-потоки Go-runtime) и channels (типизированные каналы для сообщений между goroutines). go funcName() запускает goroutine; ch <- value шлёт; value := <-ch принимает. select ждёт на нескольких каналах; context.Context несёт cancellation + дедлайны через дерево вызовов. sync.Mutex, sync.WaitGroup, sync.Once, атомарные примитивы, errgroup для группировки goroutines.
Когда применять
Goroutines используйте свободно — дёшевы (~2-4KB stack начально, растёт по нужде). Всегда имейте способ остановить goroutine (cancellation context.Context, close канала, deadline) — утёкшие goroutines = тихий рост памяти. Context первым аргументом — в любую функцию с I/O. sync.Mutex — для shared state, когда channels неудобны. errgroup — для "fan out, wait, первая ошибка пробрасывается".
Типичные ошибки
Ловушки Горутины: утечки goroutines (goroutine ждёт навеки на канале, в который никто не пишет); data race на shared map без mutex (race detector ловит: go test -race); deadlock (go test -race НЕ ловит deadlock — осторожно); не пробрасывают context.Context, и cancellation не доходит до глубокого вызова.