Потоки операционной системы планируются в ее ядре. Каждые несколько миллисекунд аппаратный таймер прерывает процессор, что приводит к вызову функции ядра, именуемой планировщиком. Эта функция приостанавливает работу текущего потока и сохраняет значения его регистров в памяти, просматривает список потоков и решает, какой из них следует запустить следующим, восстанавливает регистры этого потока из памяти и возобновляет его выполнение. Так как потоки операционной системы планируются в ядре, передача управления от одного потока к другому требует полного переключения контекста, т.е. сохранения состояния одного пользовательского потока в памяти, восстановление состояния другого и обновление структур данных планировщика. Это медленная операция — из-за слабой локальности и необходимого количества обращений к памяти.
Среда выполнения Go содержит собственный планировщик
, который использует метод, известный как m:n-планирование
,
потому что он мультиплексирует (или планирует)
выполнение m
горутин на n
потоках операционной системы. Задания
планировщика Go аналогичны заданиям планировщика ядра, но связаны только с горутинами одной программы Go.
В отличие от планировщика потоков операционной системы планировщик Go вызывается не периодически аппаратным таймером, а
неявно некоторыми конструкциями языка Go. Например, когда горутина вызывает time.Sleep
или блокируется операцией
канала
или мьютекса
, планировщик переводит ее в спящий режим и запускает другую горутину до тех пор, пока не
наступит время активировать первую. Поскольку переключение контекста ядра не требуется, планирование горутин намного
дешевле, чем потоков.
Потоки операционной системы планируются в ядре
, что требует переключения контекста и является медленной операцией из-за слабой локальности и обращений к памяти;- Go имеет собственный планировщик, который использует
m:n-планирование
, мультиплексирование (планирование)m
горутин наn
потоках операционной системы, чтобы сделать планирование быстрее и эффективнее; - Планировщик Go вызывается не периодически аппаратным таймером, а
неявно некоторыми конструкциями языка Go
, такими какtime.Sleep
,каналы
имьютексы
; - Когда горутина
блокируется на задаче
, планировщик переводит ее в спящий режим и запускает другую горутину, что позволяет эффективнее использовать ресурсы; - Планирование горутин
значительно дешевле
, чем планирование потоков, поскольку не требуется переключение контекста ядра; - Использование планировщика и горутин в Golang делает многопоточное программирование более доступным и быстрым.