Go изначально проектировался для написания высокопроизводительных сетевых и параллельных программ, поэтому особое внимание уделено встроенному планировщику (scheduler) и простому управлению параллелизмом с помощью горутин. В отличие от большинства языков, где потоки ОС напрямую управляются пользователем языка, в Go горутины легче, их тысячи могут работать одновременно поверх фиксированного числа системных потоков.
Проблема: прямое управление потоками (threads) сложно: это приводит к быстрой утилизации ресурсов, data races и сложностям управления памятью.
Решение: Go использует модель M:N — большое количество горутин (M) мультиплексируются на ограниченном количестве потоков ОС (N). За это отвечает планировщик, реализованный на уровне рантайма Go, который автоматически балансирует и перераспределяет выполнение горутин. Программист управляет только запуском и синхронизацией горутин, а не потоками ОС непосредственно.
Пример кода:
package main import ( "fmt" "time" ) func worker(id int) { fmt.Printf("Worker %d starting ", id) time.Sleep(time.Second) fmt.Printf("Worker %d done ", id) } func main() { for i := 0; i < 5; i++ { go worker(i) } time.Sleep(2 * time.Second) }
Ключевые особенности:
Будет ли каждая горутина конкурентно исполняться на отдельном ядре процессора?
Нет. Горутины мультиплексируются и планировщик определяет реальное количество конкурентно выполняемых задач.
Можно ли вручную управлять исполнением конкретных горутин/потоков?
Нет. Рантайм Go не предоставляет интерфейса для непосредственного планирования. Исключение — GOMAXPROCS для выставления числа потоков ОС.
Означает ли большое число горутин автоматическое ускорение программы?
Нет. Велико число конткурентных операций может привести к дополнительным оверхедам: переключениям контекста, contention за ресурсы, росту времени GC и потребления памяти.
Микросервис параллельно обрабатывал поступающие запросы, не ограничивал число горутин и не ожидал завершения через WaitGroup — результат: выросшее время ответа, data races, непредсказуемые таймауты.
Плюсы:
Минусы:
Менеджер воркеров реализован через пул горутин, ограничение числа одновременно работающих задач — через семафор или каналы. WaitGroup корректно ожидает завершения всех задач.
Плюсы:
Минусы: