Пример использования команды Linux nice: как управлять приоритетами процессов.

Если у вашего сервера достаточно ресурсов или он выполняет не требовательные к процессорному времени задачи, заниматься менеджментом приоритетов нет необходимости.

Однако если вы запускаете несколько программ одновременно, и они требуют много ресурсов, команда nice поможет управлять их приоритетами.

Это особенно полезно, чтобы важные задачи выполнялись быстрее, а менее важные — использовали меньше ресурсов.

Что такое команда nice? Это инструмент, который позволяет запускать программы с определённым уровнем «вежливости/уступчивости» к другим процессам. Вежливость обратно противоположна приоритету.

Она варьируется от -20 до 19. В системе это значит, что процесс с большим значением nice — более вежливый и уступает место более важным задачам. Чем ниже значение nice (например, -20), тем выше приоритет процесса. Чем выше значение (например, 19), тем ниже его приоритет.

Как узнать текущий приоритет процесса?

Чтобы посмотреть идентификатор процесса (PID) и его текущий nice, можно использовать командуps axl:

[root@waky example]# ps axl
F   UID     PID    PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
4     0       1       0  20   0 106752 15912 ep_pol Ss   ?          0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 31
1     0       2       0  20   0      0     0 kthrea S    ?          0:00 [kthreadd]
1     0       3       2   0 -20      0     0 rescue I<   ?          0:00 [rcu_gp]
…
4     0    1254    1253  20   0   7548  4096 do_wai Ss   pts/0      0:00 -bash
4     0    1278    1254  20   0  10084  3200 -      R+   pts/0      0:00 ps axl
[root@waky example]#

Она выводит список процессов с их идентификаторами PID и значениями nice (колонка NI). Обычно, наибольшим приоритетом обладают системные процессы, их значение вежливости минимально (-20).

Пользовательские процессы по умолчанию имеют среднюю уступчивость. Например, выполнение самой команды ps axl имело значение nice (0).

Подготовка к практическим примерам

С теорией все более менее понятно, пора переходить к практическим примерам. Чтобы не играться с системными процессами или программами, подготовим простой скрипт.

Его цель – некоторое время генерировать нагрузку, а на выходе вернуть время своей работы. Используйте текстовый редактор, чтобы создать файл load_gen_script.sh со следующим содержанием:

#!/bin/bash
x=0
run_start=$(date +%s%N)
while [ $x -le 10000000 ]
do
  x=$(( $x + 1 ))
done
run_end=$(date +%s%N)
run_time=$((($run_end - $run_start)/1000000000))
echo "run_time: $run_time seconds"

Цель скрипта, осуществлять простые арифметические исчисления, тем самым занимая процессорное время. Работает пока x не достигнет значения 10000000. С каждым шагом x увеличивается на 1.

В начале и в конце берутся временные метки run_start и run_end. В конце высчитывается разница меток, и переводится в секунды. Получаем run_time показывающий время исполнения скрипта в секундах.

В зависимости от ресурсов тестового окружения данный скрипт может выполняться слишком быстро или слишком медленно. В таком случае добавьте или уберите пару нулей из максимального значения x строка while [ $x -le 10000000 ].

Задаем скрипту права на исполнение с помощью команды chmod, и запускаем:

[root@waky example]# chmod 700 load_gen_script.sh
[root@waky example]# ./load_gen_script.sh
run_time: 189 seconds
[root@waky example]#

Тестовый скрипт готов, переходим непосредственно к изучению утилиты nice.

Практический пример: запуск ресурсоёмкой задачи с низким приоритетом

Так как наше тестовое окружение не выполняет никаких серьезных задач, ресурсы сервера свободны, и мы не заметим большой разницы в изменение приоритетов.

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

Запускаем имитацию нагрузки в фоновом режиме:

[root@waky example]# ./load_gen_script.sh &> /dev/null &
[1] 1460
[root@waky example]#

И сразу следом запускаем скрипт с максимальной вежливостью (низким приоритетом):

[root@waky example]# nice -n 19 ./load_gen_script.sh
run_time: 363 seconds 
[root@waky example]#

Мы запустили скрипт с наибольшим значением nice (19). В то же время, скрипт запущенный пользователем в фоновом режиме по умолчанию имеет средний приоритет. В итоге основной скрипт уступает фоновому скрипту в конкуренции за ресурсы сервера.

Устанавливая низкий приоритет для процесса, вы говорите серверу, что он может не спешить с выполнением поставленной задачи. Когда у сервера будет появляться свободное процессорное время, он будет возвращаться к вежливому процессу.

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

Практический пример: запуск тяжелой задачи с высоким приоритетом

Если у вас есть важная задача, и вы хотите дать ей больше ресурсов, запустите её с меньшим значением nice. Повторим прошлый эксперимент, но на этот раз установим минимальную вежливость (-20):

[root@waky example]# ./load_gen_script.sh &> /dev/null &
[1] 1470
[root@waky example]# nice -n -20 ./load_gen_script.sh
run_time: 189 seconds
[root@waky example]#

В результате, основной скрипт отработал в два раза быстрее. Из-за высокого приоритета, его процесс не уступал процессорное время, используя все доступные ресурсы сервера.

В итоге время работы скрипта с максимальным приоритетом равно времени его тестового запуска на этапе подготовки, когда сервер простаивал без нагрузки.

Использовать низкую вежливость стоит тогда, когда время работы процесса имеет критическое значение. Высоким приоритетом не стоит злоупотреблять, если вы зададите максимальный приоритет многим задачам, результат будет такой же, как если бы они все толкались на низком уровне.

Правильный подход – разумное распределение работ, которые выполняет сервер, по всему спектру nice.

Практический пример: как изменить приоритет уже запущенного процесса?

Если программа уже работает, но вы хотите изменить её приоритет, используйте команду renice. Например:

[root@waky example]# ./load_gen_script.sh &> /dev/null &
[4] 1525
 [root@waky example]# ps axl
F   UID     PID    PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
…
0     0    1525    1254  20   0   7124  3328 -      R    pts/0      0:07 /bin/bash ./load_gen_script.sh
…
[root@waky example]#

Наш процесс с идентификатором PID 1525 имеет среднюю вежливость (0). Повысим ее:

[root@waky example]# renice -n 10 1525
1525 (process ID) old priority 0, new priority 10
[root@waky example]# ps axl
F   UID     PID    PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
…
0     0    1525    1254  30  10   7124  3328 -      RN   pts/0      2:22 /bin/bash ./load_gen_script.sh
…
[root@waky example]#

Теперь данный процесс стал более уступчивым.

Если нужно повысить приоритет (сделать его более «агрессивным»), можно установить отрицательное значение:

[root@waky example]# renice -n -5 1525
1525 (process ID) old priority 10, new priority -5
[root@waky example]# ps axl
F   UID     PID    PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
…
0     0    1525    1254  15  -5   7124  3328 -      RN   pts/0      2:33 /bin/bash ./load_gen_script.sh
…
[root@waky example]#

В таком случае скрипт станет менее уступчивым и будет выполняться быстрее.

Для самых внимательных

Возможно, вы обратили внимание, что в выдаче ps axl присутствует отдельный столбец PRI. Это и есть приоритетность процессов.

По умолчанию, процесс имеет значение priority равное 20, а nice служит его модификатором. Итоговое значение приоритета представляет собой сумму базового значения и вежливости.

Так в последних двух примерах, когда nice = 10, priority = 20 + 10 = 30. А при nice = -5, priority = 20 + (-5) = 15.

Чем ниже значение priority, тем выше приоритет процесса. Такая обратная зависимость может путать, для простоты понимания рассматривайте приоритетность, как место в очереди. Чем меньше номер у процесса, тем быстрей его обслужат.

Заключение

Команда nice — мощный инструмент для управления приоритетами процессов в Linux. Она помогает запускать программы так, чтобы они использовали ресурсы системы наиболее эффективно и не мешали друг другу.

Зная как задавать значения nice и изменять их через renice, вы сможете лучше контролировать работу вашего сервера и делать её более плавной и стабильной.