Этот пост дает ответ на вопрос: почему Go оптимизирован под конкурентные I/O-нагруженные системы, такие как сетевые сервисы. Пост является квинтэссенцией рассуждений из комментариев в Golang HTTP Middleware: История Go, Goroutines, Инсайт.
Язык программирования это не только синтаксис, но и реализация Runtime. Runtime - это та часть выполняемой программы в которой реализованы структуры данных и алгоритмы поддерживающие синтаксические конструкции языка. А именно реализация словарей, сетов, асинхронности, многозадачности и конкурентности (что не одно и то же).
Golang уникален, а для 2010ых революционен, реализацией связки Синтаксис+Runtime под АРХЕТИПИЧЕСКИЙ дизайн программы. Архетипичная программа на Go - это сервер работающий в одном OS Process на множестве OS Thread, который обрабатывает вал HTTP запросов максимально утилизируя использование OS Threads.
Как известно исполнение алгоритма программы может блокироваться алгоритмически (что-то ждет ответа), а может физически OS Thread ждет IO. В Go оба типа блокировок сведены к минимуму через реализацию прослойки Виртуального Процессора и легковесных Горутин - таким образом переклеивая Виртуальный Процессор между OS Threads, а также тасуя ожидающие и готовые к выполнению Goroutines - реальный CPU практически не простаивает. И весь этот механизм описан простым и понятным синтаксисом.
Таким образом Go спроектирован под написание программ которые в рамках одного OS Process самым оптимальным образом обрабатывают максимально число запросов выше Транспортного Уровня. Архетипический дизайн программы - есть слушающая горутина, она запускает на каждое соединение обрабатывающие горутины. Остальное отдается на откуп Runtime. А Runtime в свою очередь обрабатывает последовательность выполнения горутин на разных Виртуальных Процессорах и разных OS Thread.
// Core of the Architypical Go Application
listener, _ := net.Listen("tcp", ":8080")
for {
conn, _ := listener.Accept()
go handle(conn)
}
Модель планировщика Go называется G/P/M - Goroutine/ProcessorVirtual/MachineThread, или еще по другому N:M, N горутин выполняется на M OS Threads. Иногда ее зову M:N, но я предпочитаю оставлять букву M за OS Threads.
🎆 Суть в одном абзаце от ChatGPT:
Go спроектирован так, чтобы упростить разработку конкурентных I/O-нагруженных систем. Этого достигают за счёт встроенной модели goroutines и runtime-планировщика, который распределяет их выполнение между ограниченным числом OS threads (M:N scheduling). В результате разработчик пишет простой синхронный код, а конкурентность и переключение задач управляются runtime.













