Runtime в Go — это система времени выполнения, которая управляет выполнением Go-программ. Она отвечает за:
- Планирование: Использует планировщик M:N, который связывает M легковесных горутин с N системными потоками ОС. Это позволяет эффективно использовать ядра процессора.
- Управление памятью: Реализует автоматический сборщик мусора (GC), который периодически высвобождает неиспользуемую память. GC в Go — Concurrent, Tri-color Mark-and-sweep, что позволяет ему работать одновременно с пользовательским кодом и сокращать паузы.
- Управление горутинами: Создание, выполнение, переключение контекста и завершение горутин. Горутины легче потоков ОС, их создание и переключение контекста менее затратно.
- Каналы (Channels): Реализует механизм синхронизации и обмена данными между горутинами. Каналы могут быть буферизованными или небуферизованными.
- Сетевые операции: Встроенные примитивы для работы с сетью, которые интегрированы с планировщиком.
- Системные вызовы: Абстрагирует взаимодействие с операционной системой.
Основные компоненты планировщика:
- M (Machine): Поток ОС.
- P (Processor): Логический процессор, представляющий контекст, в котором выполняются горутины (G). Каждый P имеет локальную очередь готовых к выполнению горутин (
runqueue). Количество P по умолчанию равно runtime.NumCPU().
- G (Goroutine): Легковесный поток выполнения.
Когда горутина готова к выполнению, она помещается в локальную очередь P. Если локальная очередь P пуста, планировщик может "украсть" горутину из очереди другого P (work stealing). Если все P заняты и их локальные очереди пусты, планировщик может забрать горутину из глобальной очереди.
Операции ввода/вывода блокирующие для горутин, но не для потоков ОС. Когда горутина выполняет блокирующий системный вызов, она отключается от своего P, а планировщик подключает к этому P другую готовую горутину. Поток ОС (M) становится блокированным, пока системный вызов не завершится. После завершения системного вызова горутина снова становится доступной для планирования и может быть назначена на любой свободный P.
Пример создания горутины:
go
Пример использования канала:
go