Время выполнения (runtime) в Go — это среда, в которой выполняются Go-программы. Она включает в себя:
- Управление памятью: Сборщик мусора (garbage collector) автоматически управляет выделением и освобождением памяти.
- Планировщик (scheduler): Управляет выполнением горутин на потоках операционной системы.
- Системные вызовы: Предоставляет интерфейс для взаимодействия с операционной системой.
- Примитивы синхронизации: Каналы, мьютексы и другие механизмы для координации горутин.
Планировщик Go реализует модель M:N (множество горутин на множестве потоков ОС). Его основные компоненты:
- G (Goroutine): Легковесный поток выполнения, по сути абстракция над функцией.
- M (Machine): Поток операционной системы, на котором выполняются Go-программы.
- P (Processor): Логический процессор, связанный с потоком ОС. Он хранит локальную очередь
runnable горутин.
Принцип работы планировщика:
- Горутины (G) создаются и добавляются в глобальную или локальную очередь
runnable.
- Потоки ОС (M) ассоциируются с логическими процессорами (P). Количество P по умолчанию равно количеству ядер CPU (
GOMAXPROCS).
- P забирает горутину из своей локальной очереди. Если локальная очередь пуста, P пытается "украсть" (steal) горутины из очереди другого P или из глобальной очереди.
- M выполняет горутину.
- Когда горутина блокируется (например, при чтении из канала без данных или выполнении системного вызова), M отсоединяется от P, и P становится доступен для выполнения другой горутины. Блокированная горутина ставится в ожидание. Когда блокировка снимается, горутина снова становится
runnable и ставится обратно в очередь.
- Если M блокируется в системном вызове, он не удерживает P. Новый M может быть создан или использован существующий, чтобы P мог продолжить выполнение других горутин.
Этот подход позволяет эффективно использовать ресурсы процессора и легко масштабировать параллельные задачи, скрывая сложность управления потоками ОС от разработчика.
go