Разница в том, что в настоящий момент PR является реальным приоритетом процесса внутри ядра, а NI - просто подсказка ядру, какой приоритет должен иметь процесс.
В большинстве случаев значение PR можно рассчитать по следующей формуле: PR = 20 + NI. Таким образом, процесс с милостью 3 имеет приоритет 23 (20 + 3), а процесс с милостью -7 имеет приоритет 13 (20 - 7). Вы можете проверить первое, выполнив команду nice -n 3 top
. Это покажет, что топ процесс имеет NI 3 и PR 23. Но для запуска nice -n -7 top
в большинстве систем Linux вам необходимо иметь привилегии root, потому что на самом деле чем меньше значение PR, тем выше фактический приоритет. Таким образом, процесс с PR 13 имеет более высокий приоритет, чем процессы с стандартным приоритетом PR 20. Вот почему вам нужно быть пользователем root. Но минимальное допустимое значение для процесса без полномочий root можно настроить в /etc/security/limits.conf.
Теоретически ядро может изменить значение PR (но не NI) само по себе. Например, он может уменьшить приоритет процесса, если он потребляет слишком много ресурсов ЦП, или он может повысить приоритет процесса, если этот процесс не имел возможности долго работать из-за других процессов с более высоким приоритетом. В этих случаях значение PR будет изменено ядром, и NI останется неизменным, поэтому формула "PR = 20 + NI" будет неправильной. Таким образом, значение NI можно интерпретировать как подсказку для ядра о том, какой приоритет должен иметь процесс, но ядро может выбирать реальный приоритет (значение PR) самостоятельно в зависимости от ситуации. Но обычно формула «PR = 20 + NI» верна.
Точные правила того, как ядро меняет приоритет, не ясны. Инструкция setpriority (функция, которая изменяет значение nice) гласит:
Эффект изменения значения nice может варьироваться в зависимости от действующего алгоритма планирования процесса.
Руководство Pthread гласит следующее:
Динамический приоритет основан на значении nice(устанавливается параметрами nice(2), setpriority(2) или sched_setattr(2)) и увеличивается каждый раз, когда квант готов к запуску потока, но запрещен для запуска планировщиком.
Кажется, что значение PR соответствует динамическому приоритету.
Диапазон значения NI составляет -20..19. Таким образом, значение PR может иметь значения от 0 (20 - 20) до 39 (20 + 19). Но это верно только для процессов с политикой планирования по умолчанию (SHED_OTHER). Также могут быть процессы с так называемыми политиками планирования в реальном времени. Это политики SCHED_RR и SCHED_FIFO. Такие процессы имеют значение PR менее 0. Вы можете проверить это, выполнив chrt -r 1 top
(должен быть пользователем root). Верхний процесс будет иметь PR -2. Вы даже можете запустить chrt -r 90 top
в этом случае процесс top будет иметь PR -91.
Кажется, что для процессов SCHED_RR значение PR можно рассчитать по формуле:
PR = - 1 - sched_rr_priority.
Таким образом , процесс SCHED_RR имеет , по крайней мере , PR -1 , что означает , что любой процесс SCHED_RR имеет более высокий приоритет , чем любая SCHED_OTHER. Это соответствует руководству pthread:
SCHED_FIFO может использоваться только со статическими приоритетами выше 0, что означает, что, когда потоки SCHED_FIFO становятся работоспособными, они всегда будут немедленно вытеснять любой текущий запущенный поток SCHED_OTHER, SCHED_BATCH или SCHED_IDLE.
SCHED_RR - это простое улучшение SCHED_FIFO. Все, что описано выше для SCHED_FIFO, также относится к SCHED_RR,
Приоритет процессов реального времени называется статическим приоритетом, который не может быть изменен ядром. Таким образом , положительные значения PR можно рассматривать как динамический приоритет для не в реальном времени (SCHED_OTHER, SCHED_BATCH) процессов и отрицательного значения PR в качестве статического приоритета для процессов в реальном времени (SCHED_RR, SCHED_FIFO).
Я также попытался запустить nice -n 10 chrt -r 50 top
(и chrt -r 50 nice -n 10 top
). Значение NI было 10, но PR все еще был -51. Таким образом, кажется, что значение NI не влияет на приоритет процессов SCHED_RR. Это соответствует руководству по установке приоритетов :
Любые процессы или потоки, использующие SCHED_FIFO или SCHED_RR, не должны подвергаться воздействию вызова setpriority(). Это не считается ошибкой. Процесс, который впоследствии возвращается к SCHED_OTHER, не должен подвергаться влиянию своего приоритета таким вызовом setpriority().
Одна забавная записка. Если вы запустите chrt -r 99 top
, вы увидите значение RT вместо числа в столбце PR .
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28489 root RT 0 2852 1200 896 R 0 0.1 0:00.01 top
Я не думаю, что это означает, что процесс сейчас особенный. Я думаю, это означает, что top не печатает -100, потому что для печати потребуется 4 символа.
Вы также можете использовать htop вместо top во всех примерах, что может быть более удобным. ps -l
может быть использован, но его базовая точка, которая разделяет приоритеты в реальном времени и не в реальном времени, не 0, а 60, так что nice -n -20 ps -l
выведет
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 R 0 28983 28804 0 60 -20 - 1176 - pts/6 00:00:00 ps