Горутины: планировщик
Не все горутины в рабочем состоянии выполняются в данный момент времени. В любой момент времени максимальное количество выполняемых горутин не будет превышать количество логических процессоров, доступных для текущей программы. Мы можем вызвать runtime.NumCPU функцию (подробнее изучить ее ты можешь по ссылке), чтобы получить количество логических процессоров, доступных для текущей программы. Каждый логический ЦП может выполнять только одну горутину в любой момент времени. Среда выполнения Go должна часто переключать контексты выполнения между горутинами, чтобы каждая запущенная горутина могла выполниться. Это похоже на то, как операционные системы переключают контексты выполнения между потоками ОС.
На следующем рисунке показан более подробный возможный жизненный цикл горутины. На картинке рабочее состояние разделено еще на несколько подсостояний. Горутина в подсостоянии очереди ожидает выполнения. Горутина в подсостоянии выполнения может снова войти в подсостояние очереди, если она выполнялась какое-то время — это очень маленький отрезок времени.

Обрати внимание: для простоты подсостояния, показанные на рисунке выше, не будут упоминаться нами далее. И снова — подсостояния сна и системного вызова не рассматриваются как подсостояния, блокирующее состояние в приложении.
Стандартная среда выполнения Go использует модель MPG для выполнения задания планирования горутин, где M представляет потоки ОС, P представляет логические/виртуальные процессоры (не логические ЦП), а G представляет горутины. Большая часть запланированной работы выполняется логическими процессорами (Ps), которые действуют как посредники, присоединяя горутины (Gs к потокам ОС (Mс). Каждый поток ОС может быть присоединен не более чем к одной горутине в любой момент времени, и каждая горутина может быть присоединена не более чем к одному потоку ОС в любой момент времени. Горутина может выполняться только тогда, когда она присоединена к потоку ОС. Горутина, которая выполнялась какое-то время, попытается отсоединиться от соответствующего потока ОС, чтобы другие запущенные горутины могли присоединиться и выполниться.
Во время выполнения мы можем вызвать runtime.GOMAXPROCS функцию для получения и установки числа логических процессоров (Ps). Для стандартной среды выполнения Go до Go 1.5 начальное значение этого числа по умолчанию равно 1, но начиная с Go 1.5 начальное значение этого числа по умолчанию равно количеству логических процессоров, доступных для текущей запущенной программы. Начальное значение по умолчанию (количество логических процессоров) лучше всего подходит для большинства программ. Но для некоторых программ с тяжелым файловым вводом-выводом GOMAXPROCS значение больше runtime.NumCPU() может быть полезным.
Начальное значение по умолчанию runtime.GOMAXPROCS также может быть установлено через GOMAXPROCS переменную окружения.
В любой момент количество горутин в выполняющемся подсостоянии не больше, чем меньшее из runtime.NumCPU и runtime.GOMAXPROCS.