Планировщик Go: GOMAXPROCS, вытеснение и блокирующие системные вызовы
Планировщик Go построен по схеме «горутина — логический процессор — поток ОС». Логических процессоров ровно GOMAXPROCS, и это верхняя граница кода Go, исполняющегося параллельно; с Go 1.25 значение по умолчанию учитывает лимит CPU в cgroups, поэтому в контейнере с квотой в два ядра Go больше не считает, что у него 64. У каждого логического процессора своя локальная очередь горутин, есть общая очередь, и простаивающий процессор крадёт работу у соседей. Блокирующий системный вызов не блокирует остальных: поток уходит в ядро вместе с горутиной, а логический процессор отвязывается и подхватывает другой поток — поэтому файловый ввод-вывод не останавливает сервис. С Go 1.14 планировщик асинхронно вытесняющий: сигнал прерывает горутину, крутящуюся в длинном цикле, чего раньше не происходило и приводило к зависанию сборки мусора. Диагностируется всё это трассировкой выполнения, а не догадками.