Итак, если я установил привязку к процессору, используя:

sched_setaffinity()

А затем выполнить другой системный вызов, используя этот процесс, ТАКЖЕ гарантировано ли выполнение этого системного вызова на том же процессоре, принудительно выполняемом sched_setaffinity?

По сути, я пытаюсь добиться, чтобы процесс и выполняемые им системные вызовы выполнялись на одном ядре. Очевидно, я могу использовать sched_setaffinity() для принудительного выполнения кода пользовательского пространства только на одном процессоре, но будет ли тот же системный вызов принудительно выполнять код пространства ядра в этом контексте процесса на том же ядре?

Благодарность!

1
Roguebantha 15 Апр 2020 в 01:37

1 ответ

Лучший ответ

Системные вызовы - это просто переключение кода вашего процесса из пользовательского режима в режим ядра. Выполняемая задача вообще не меняется, она просто временно переходит в режим ядра для выполнения системного вызова, а затем возвращается в пользовательский режим.

Планировщик может прервать выполнение задачи и переместить ее на другой ЦП, и это может произойти в середине кода обычного пользовательского режима или даже в середине системного вызова.

Устанавливая привязку задачи к одному ЦП с помощью sched_setaffinity(), вы устраняете эту возможность, поскольку даже если задача будет вытеснена, у планировщика нет другого выбора, кроме как поддерживать ее работу на том же ЦП (это, конечно, может изменить текущая задача, но когда ваша задача возобновится, она все еще будет на том же процессоре).

Итак, чтобы ответить на ваш вопрос:

будет ли тот же системный вызов принудительно выполнять код пространства ядра в этом контексте процесса на том же ядре?

Да.


Теперь обратимся к комментарию @Barmar: в случае системных вызовов, которые могут "спать", это не означает, что задача может изменить ЦП, если этого не позволяет родство.

Когда системный вызов засыпает, код системного вызова просто сообщает планировщику: «Эй, я чего-то жду, просто запустите другое задание, пока я жду, и разбудите меня позже». Когда системный вызов возобновляется, он проверяет, доступен ли запрошенный ресурс (он может даже сказать ядру, когда он хочет проснуться), а если нет, он либо ждет снова, либо возвращается к пользовательскому коду, говоря "извините, ничего не получилось, попробуйте еще раз". Ресурс, конечно, может быть доступен с помощью некоторого прерывания, которое заставляет обработчик прерывания запускаться на другом процессоре, но это другая история, и на самом деле это не имеет значения. Проще говоря: код прерывания вообще не запускается в контексте процесса. Что касается задачи, выполняющей системный вызов, ресурс просто волшебным образом присутствует там, когда выполнение возобновляется.

1
Marco Bonelli 4 Май 2020 в 21:50