Изучаем Linux, 101: Приоритеты исполнения процесса

Источник: IBM

Краткий обзор

Из этой статьи вы узнаете об основных приемах управления приоритетами исполнения процессов в Linux. Вы научитесь:

  • Понимать, что такое приоритеты процессов.
  • Назначать приоритеты процессов.
  • Изменять приоритеты процессов.

Эта статья поможет вам подготовиться к сдаче экзамена LPI 101 на администратора начального уровня (LPIC-1) и содержит материалы цели 103.6 темы 103. Цель имеет вес 2.

Чтобы извлечь наибольшую пользу из наших статей, необходимо обладать базовыми знаниями о Linux и иметь работоспособный компьютер с Linux, на котором можно будет выполнять все встречающиеся команды. Иногда различные версии программ выводят результаты по-разному, поэтому содержимое листингов и рисунков может отличаться от того, что вы увидите на вашем компьютере. Все примеры этой статьи были выполнены в операционной системе Ubuntu 9.10 (Karmic Koala). В основе этой статьи лежит концепция, описанная в предыдущей статье этой серии "Изучаем Linux, 101: создание, отслеживание и уничтожение процессов".

Получение информации о приоритетах процессов

В Linux, как и во всех современных операционных системах, одновременно может выполняться несколько процессов. Это достигается путем разделения процессорных и других ресурсов между процессами. Если какой-то процесс использует ресурсы центрального процессора на 100%, то все остальные процессы могут перестать отвечать на запросы.

Если вы запустите команду top, то по умолчанию она отобразит процессы, отсортированные по степени использования ресурсов ЦП в убывающем порядке, как показано в листинге 1. В предыдущей статье этой серии "Изучаем Linux, 101: создание, отслеживание и уничтожение процессов" мы создали сценарий простых цифровых часов, который выводил на экран время с интервалом в 30 секунд, а в остальное время ничего не делал. Если бы у нас был запущен такой процесс, то, вероятно, он бы не повлиял на вывод команды top, поскольку большую часть времени он не использует ресурсы центрального процессора.

Листинг 1. Типовой вывод команды top на компьютере под управлением Linux

top - 08:00:52 up 1 day, 10:20,  5 users,  load average: 0.04, 0.08, 0.04
Tasks: 172 total,   1 running, 171 sleeping,   0 stopped,   0 zombie
Cpu(s):  3.7%us,  0.3%sy,  0.0%ni, 95.6%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Mem:   4057976k total,  1777976k used,  2280000k free,   225808k buffers
Swap: 10241428k total,        0k used, 10241428k free,   655796k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            
11220 ian       20   0  555m 106m  27m S    8  2.7  36:06.16 firefox            
    7 root      15  -5     0    0    0 S    1  0.0  10:59.36 ksoftirqd/1        
10849 ian       20   0  212m  15m  10m S    0  0.4   0:08.11 gnome-terminal     
    1 root      20   0 19584 1888 1196 S    0  0.0   0:00.83 init               
    2 root      15  -5     0    0    0 S    0  0.0   0:00.01 kthreadd           
    3 root      RT  -5     0    0    0 S    0  0.0   0:00.02 migration/0        
    4 root      15  -5     0    0    0 S    0  0.0   0:01.08 ksoftirqd/0        
    5 root      RT  -5     0    0    0 S    0  0.0   0:00.00 watchdog/0         
    6 root      RT  -5     0    0    0 S    0  0.0   0:00.03 migration/1        
            

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

Когда количество имеющихся в вашем распоряжении процессоров ограничено, необходимо решить, как распределить имеющиеся ресурсы между несколькими конкурирующими процессами. Обычно эта задача решается так: выбирается какой-то один процесс, который выполняется на протяжении короткого отрезка времени (другое его название - квант времени , т. е. количество процессорного времени, выделяемого приложению) либо до тех пор, пока он не переходит в состояние ожидания какого-либо события, например, завершения операции ввода/вывода. Чтобы важные процессы всегда имели необходимые им процессорные ресурсы, которые могут оказаться занятыми другими ресурсоемкими приложениями, выбор производится на базе распределения машинного времени . Столбец NI в листинге 1 показывает распределение машинного времени (приоритет, или т. н. niceness ) для каждого процесса. Как правило, значение niceness варьируется от -20 до 19; -20 означает наивысший приоритет, а 19 - наименьший приоритет.

Как узнать приоритет с помощью ps

Помимо команды top для определения значений приоритета (niceness) можно использовать команду ps. Вы можете настроить вывод одним из способов, описанных в статье "Изучаем Linux, 101: создание, отслеживание и уничтожение процессов", или просто использовать опцию -l для вывода подробного списка. Вывод команды ps -l представлен в листинге 2. Как и в случае с командой top, значение приоритета отображается в столбце NI.

Листинг 2. Использование ps для поиска значений niceness

                    
ian@attic4:~$ ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000 26502 26501  0  80   0 -  5368 wait   pts/4    00:00:00 bash
0 R  1000 27046 26502  0  80   0 -  1684 -      pts/4    00:00:00 ps


Значение приоритета по умолчанию

Из листингов 1 и 2 видно, что значением приоритета по умолчанию (по крайней мере, для процессов, запущенных обычными пользователями) является 0. Вы можете посмотреть значение приоритета для командного интерпретатора и системы, запустив команду nice без параметров, как показано в листинге 3.

Листинг 3. Проверка значения приоритета по умолчанию

                    
ian@attic4:~$ nice
0

Установка приоритетов

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

Сценарий, загружающий процессор

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

Листинг 4. Сценарий, загружающий ЦП

                    
ian@attic4:~$ echo 'x="$1"'>count1.sh
ian@attic4:~$ echo 'echo "$2" $(date)'>>count1.sh
ian@attic4:~$ echo 'while [ $x -gt 0 ]; do x=$(( x-1 ));done'>>count1.sh
ian@attic4:~$ echo 'echo "$2" $(date)'>>count1.sh
ian@attic4:~$ cat count1.sh
x="$1"
echo "$2" $(date)
while [ $x -gt 0 ]; do x=$(( x-1 ));done
echo "$2" $(date)

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

Листинг 5. Запуск сценария count1.sh

                    
ian@attic4:~$ sh count1.sh 10000 A
A Wed Jan 20 08:34:16 EST 2010
A Wed Jan 20 08:34:16 EST 2010
ian@attic4:~$ bash count1.sh 99000 A
A Wed Jan 20 08:34:20 EST 2010
A Wed Jan 20 08:34:22 EST 2010

Пока все хорошо. Давайте теперь создадим список команд для запуска сценария в фоновом режиме, после чего с помощью команды top посмотрим, сколько ресурсов процессора он расходует (чтобы освежить ваши знания о списках команд, обратитесь к статье "Изучаем Linux, 101: командная строка Linux"). Список команд показан в листинге 6, а вывод команды top - в листинге 7.

Листинг 6. Запуск сценария count1.sh и команды top

                    
ian@attic4:~$ (sh count1.sh 5000000 A&);top

Листинг 7. Интенсивное использование ресурсов ЦП

                    
top - 15:41:15 up 1 day, 17:59,  6 users,  load average: 0.20, 0.06, 0.02
Tasks: 169 total,   2 running, 167 sleeping,   0 stopped,   0 zombie
Cpu(s): 52.1%us,  0.7%sy,  0.0%ni, 47.3%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   4057976k total,  1393772k used,  2664204k free,   235596k buffers
Swap: 10241428k total,        0k used, 10241428k free,   662592k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
26756 ian       20   0  4004  588  496 R  100  0.0   0:03.53 sh
11220 ian       20   0  555m 101m  27m S    5  2.6  57:58.07 firefox
26757 ian       20   0 19132 1364  980 R    0  0.0   0:00.03 top
    1 root      20   0 19584 1888 1196 S    0  0.0   0:00.89 init
    2 root      15  -5     0    0    0 S    0  0.0   0:00.01 kthreadd

Неплохо. Запустив наш сценарий, мы используем ресурсы центрального процессора на 100%. Если вы хотите загрузить несколько процессоров, вы можете добавить в список команд запуск дополнительных экземпляров count1.sh. Если такая задача будет выполняться продолжительное время, то вы (или другие пользователи) заметите, что она существенно влияет на скорость работы компьютера.

Использование nice для назначения приоритетов

Теперь, когда наша система какое-то время нагружена, давайте посмотрим, как можно установить приоритет для процесса. Давайте подведем краткие итоги уже пройденного материала.

  • В операционных системах Linux и UNIX® используется система приоритетов, всего 40 уровней, начиная с -20 (наивысший приоритет) и заканчивая 19 (низший приоритет).
  • Процессы, запущенные обычными пользователями, обычно имеют приоритет 0.
  • Команда ps может показать приоритет процесса (например, значение nice или NI) с помощью опции -l.
  • Команда nice показывает приоритет по умолчанию.

Команду nice можно также использовать для запуска процесса с другим приоритетом. Опция -n (или --adjustment) с положительным значением повышает приоритет, а эта же опция с отрицательным значением - понижает его. Помните, что процесс с наименьшим приоритетом имеет максимальное значение параметра niceness, поэтому увеличение этого значения означает, что процесс становится более дружелюбным по отношению к другим процессам. Заметьте, что, как правило, понижать значение приоритетов процессов может только суперпользователь (root). Другими словами, обычные пользователи могут делать процессы лишь более дружелюбными.

Чтобы продемонстрировать использование команды nice для установки приоритетов, давайте запустим два экземпляра сценария count1.sh в различных подоболочках, но одному из них назначим максимальное значение параметра niceness 19. Через секунду запустим команду ps -l, чтобы посмотреть статус процесса, включая значение niceness. Наконец, добавим произвольную паузу в интервале 30 секунд, чтобы убедиться, что последовательность команд завершится только после завершения работы подоболочек. Таким образом, мы не увидим новое приглашение, пока ожидаем вывода. Результаты представлены в листинге 8.

Листинг 8. Использование nice для установки приоритетов для двух процессов

                   
ian@attic4:~$ (sh count1.sh 2000000 A&);(nice -n 19 sh count1.sh 2000000 B&);\
> sleep 1;ps -l;sleep 10
A Thu Jan 21 14:38:39 EST 2010
B Thu Jan 21 14:38:39 EST 2010
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 R  1000   946     1 99  80   0 -  1001 -      pts/3    00:00:01 sh
0 R  1000   948     1 99  99  19 -  1001 -      pts/3    00:00:01 sh
0 R  1000   952 32408  0  80   0 -  1684 -      pts/3    00:00:00 ps
0 S  1000 32408 32407  0  80   0 -  5368 wait   pts/3    00:00:02 bash
A Thu Jan 21 14:38:45 EST 2010
B Thu Jan 21 14:38:45 EST 2010

Оба задания завершились одновременно несмотря на разные приоритеты. Дело в том, что сценарий использует ресурсы одного процессора, а на моем компьютере установлен двуядерный процессор AMD Athlon™ 7750, который практически не загружен, поэтому каждый из двух процессов выполнялся на отдельном ядре, а необходимость в установке приоритетов в данном случае отсутствовала.

Давайте теперь запустим четыре процесса с различными значениями niceness (0, 6, 12 и 18) и посмотрим, что произойдет в этом случае. Для каждого процесса мы увеличили значение счетчика, чтобы они выполнялись немного дольше. Прежде чем переходить к листингу 9, подумайте, каких результатов можно ожидать теперь, исходя из того, что вы уже видели.

Листинг 9. Использование nice для назначения приоритетов для четырех процессов

                   
ian@attic4:~$ (sh count1.sh 5000000 A&);(nice -n 6 sh count1.sh 5000000 B&);\
> (nice -n 12 sh count1.sh 5000000 C&);(nice -n 18 sh count1.sh 5000000 D&);\
> sleep 1;ps -l;sleep 30
A Thu Jan 21 16:06:00 EST 2010
C Thu Jan 21 16:06:00 EST 2010
D Thu Jan 21 16:06:00 EST 2010
B Thu Jan 21 16:06:00 EST 2010
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 R  1000  1422     1 94  80   0 -  1001 -      pts/3    00:00:00 sh
0 R  1000  1424     1 42  86   6 -  1001 -      pts/3    00:00:00 sh
0 R  1000  1427     1 56  92  12 -  1001 -      pts/3    00:00:00 sh
0 R  1000  1431     1 14  98  18 -  1001 -      pts/3    00:00:00 sh
0 R  1000  1435 32408  0  80   0 -  1684 -      pts/3    00:00:00 ps
0 S  1000 32408 32407  0  80   0 -  5368 wait   pts/3    00:00:02 bash
A Thu Jan 21 16:06:14 EST 2010
B Thu Jan 21 16:06:17 EST 2010
C Thu Jan 21 16:06:26 EST 2010
D Thu Jan 21 16:06:30 EST 2010

Установив четыре различных приоритета, мы видим эффект, который заключается в том, что все задания завершились по порядку. Попробуйте поэкспериментировать с различными значениями приоритетов и самостоятельно проанализировать полученные результаты.

И последнее замечание относительно запуска процессов при помощи nice: как и в случае с командой nohup, в качестве аргумента nice нельзя использовать конвейер или список команд.

Изменение приоритетов

Команда renice

Если вы запустили процесс и поняли, что он должен выполняться с другим приоритетом, то существует способ изменить приоритет работающего процесса с помощью команды renice. В листинге 10 показано, как указать абсолютное значение (а не величину изменения) приоритета одного или нескольких процессов.

Листинг 10. Использование renice для изменения приоритетов

                    
ian@attic4:~$ sh count1.sh 10000000 A&
[1] 1537
ian@attic4:~$ A Thu Jan 21 16:17:16 EST 2010
sh count1.sh 1renice 1 1537;ps -l 1537
1537: old priority 0, new priority 1
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY        TIME CMD
0 R  1000  1537 32408 99  81   1 -  1001 -      pts/3      0:13 sh count1.sh 100
ian@attic4:~$ renice +3 1537;ps -l 1537
1537: old priority 1, new priority 3
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY        TIME CMD
0 R  1000  1537 32408 99  83   3 -  1001 -      pts/3      0:18 sh count1.sh 100

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

Дополнительную информацию о командах nice и renice вы можете найти на соответствующих man-страницах.


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=29146