Что такое воркстилинг в планировщике Go и как он работает
Что проверяют
Знаете ли вы устройство планировщика и что именно и у кого крадут. Вопрос хорошо отделяет тех, кто разбирался в связке горутин, потоков и логических процессоров, от тех, кто повторяет тезис про дешёвые горутины.
Как отвечать
Сначала три сущности. Горутина это задача. Поток операционной системы это исполнитель. Логический процессор это контекст выполнения с локальной очередью готовых горутин, и работать может только тот поток, которому достался такой контекст. Число контекстов по умолчанию равно числу доступных ядер.
У каждого контекста своя очередь ограниченного размера плюс отдельный слот для последней разбуженной горутины, а на всех есть ещё общая очередь. Локальная очередь читается почти без синхронизации, в этом и смысл схемы.
Когда локальная очередь опустела, контекст не засыпает: сначала заглядывает в общую очередь и к сетевому опрашивателю, затем выбирает случайный другой контекст и забирает у него примерно половину очереди. Случайный выбор нужен, чтобы освободившиеся не ломились в одного и того же соседа.
Хорошо добавить деталей: при переполнении локальной очереди часть горутин уезжает в общую, чтобы их увидели остальные; общая очередь периодически проверяется принудительно, иначе горутины в ней голодали бы; на блокирующем системном вызове контекст отцепляется от потока и передаётся другому, поэтому остальные горутины продолжают работать.
Где спотыкаются
Говорят, что задачи крадут у менее загруженного. Крадут у того, у кого работа есть, и забирают сразу половину очереди, чтобы одна кража окупила накладные расходы на синхронизацию.
Путают сущности и называют воркером саму горутину. Горутина это единица работы, а исполнитель это поток с логическим процессором. Ошибка немедленно вылезает на следующем вопросе про то, что настраивает GOMAXPROCS.
Считают, что кража решает любую проблему с балансировкой. Плотный счётный цикл раньше мог занимать поток надолго, сейчас планировщик вытесняет его асинхронно, но вызов, который блокирует поток целиком, всё равно отнимает исполнителя у всей программы, и кража тут не помогает.