Использование ps, kill и nice для управления процессами в Linux

Введение

Сервер Linux, как и любой другой компьютер, использует приложения. Компьютер рассматривает эти приложения как процессы.

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

В этом учебном модуле мы расскажем о некоторых простых аспектах управления процессами. Linux предоставляет широкий выбор инструментов для этой цели.

В качестве примера мы используем Ubuntu 12.04 VPS, но любые современные дистрибутивы Linux будут работать аналогичным образом.

Просмотр запущенных процессов в Linux

top

Чтобы посмотреть, какие процессы запущены на вашем сервере, нужно запустить команду top:

top***  top - 15:14:40 up 46 min,  1 user,  load average: 0.00, 0.01, 0.05 Tasks:  56 total,   1 running,  55 sleeping,   0 stopped,   0 zombie Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st Mem:   1019600k total,   316576k used,   703024k free,     7652k buffers Swap:        0k total,        0k used,        0k free,   258976k cached   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND               1 root      20   0 24188 2120 1300 S  0.0  0.2   0:00.56 init                   2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd               3 root      20   0     0    0    0 S  0.0  0.0   0:00.07 ksoftirqd/0            6 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/0            7 root      RT   0     0    0    0 S  0.0  0.0   0:00.03 watchdog/0             8 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 cpuset                 9 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 khelper               10 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kdevtmpfs           

В верхней части подборки приведена статистика по системе, в том числе сведения о нагрузке и общем количестве задач.

Вы можете легко увидеть, что в системе запущен 1 процесс, а 55 процессов находятся в режиме сна (т. е. не активны/не используют ресурсы ЦП).

В нижней части отображаются запущенные процессы и статистика их использования.

htop

В репозиториях доступна улучшенная версия top, которая называется htop. Установите ее с помощью следующей команды:

sudo apt-get install htop 

Если мы запустим команду htop, мы увидим отображение информации в более удобном формате:

htop***    Mem[|||||||||||           49/995MB]     Load average: 0.00 0.03 0.05   CPU[                          0.0%]     Tasks: 21, 3 thr; 1 running   Swp[                         0/0MB]     Uptime: 00:58:11   PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command  1259 root       20   0 25660  1880  1368 R  0.0  0.2  0:00.06 htop     1 root       20   0 24188  2120  1300 S  0.0  0.2  0:00.56 /sbin/init   311 root       20   0 17224   636   440 S  0.0  0.1  0:00.07 upstart-udev-brid   314 root       20   0 21592  1280   760 S  0.0  0.1  0:00.06 /sbin/udevd --dae   389 messagebu  20   0 23808   688   444 S  0.0  0.1  0:00.01 dbus-daemon --sys   407 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.02 rsyslogd -c5   408 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.00 rsyslogd -c5   409 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.00 rsyslogd -c5   406 syslog     20   0  243M  1404  1080 S  0.0  0.1  0:00.04 rsyslogd -c5   553 root       20   0 15180   400   204 S  0.0  0.0  0:00.01 upstart-socket-br 

Вы можете узнать больше об использовании top и htop здесь.

Использование ps для вывода перечня процессов

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

Однако эти инструменты не всегда достаточно гибкие, чтобы охватывать все сценарии. Решить эту проблему может помочь мощная команда ps.

При вызове без аргументов вывод может быть довольно сжатым:

ps***    PID TTY          TIME CMD  1017 pts/0    00:00:00 bash  1262 pts/0    00:00:00 ps 

Вывод показывает все процессы, связанные с текущим пользователем и текущим сеансом терминала. Это имеет смысл, потому что мы запускаем на этом терминале только bash и ps.

Чтобы получить более полное представление о процессах в данной системе, мы можем использовать следующую команду:

ps aux***  USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND root         1  0.0  0.2  24188  2120 ?        Ss   14:28   0:00 /sbin/init root         2  0.0  0.0      0     0 ?        S    14:28   0:00 [kthreadd] root         3  0.0  0.0      0     0 ?        S    14:28   0:00 [ksoftirqd/0] root         6  0.0  0.0      0     0 ?        S    14:28   0:00 [migration/0] root         7  0.0  0.0      0     0 ?        S    14:28   0:00 [watchdog/0] root         8  0.0  0.0      0     0 ?        S<   14:28   0:00 [cpuset] root         9  0.0  0.0      0     0 ?        S<   14:28   0:00 [khelper] . . . 

Эти опции предписывают ps показать процессы, принадлежащие всем пользователям (вне зависимости от привязки терминала) в удобном формате.

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

ps axjf***   PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND     0     2     0     0 ?           -1 S        0   0:00 [kthreadd]     2     3     0     0 ?           -1 S        0   0:00  _ [ksoftirqd/0]     2     6     0     0 ?           -1 S        0   0:00  _ [migration/0]     2     7     0     0 ?           -1 S        0   0:00  _ [watchdog/0]     2     8     0     0 ?           -1 S<       0   0:00  _ [cpuset]     2     9     0     0 ?           -1 S<       0   0:00  _ [khelper]     2    10     0     0 ?           -1 S        0   0:00  _ [kdevtmpfs]     2    11     0     0 ?           -1 S<       0   0:00  _ [netns] . . . 

Как видите, процесс kthreadd отображается как родитель процесса ksoftirqd/0 и других процессов.

Примечание об идентификаторах процессов

В системах Linux и Unix каждому процессу назначается идентификатор процесса или PID. Операционная система использует их для идентификации и отслеживания процессов.

Чтобы быстро узнать PID процесса, вы можете использовать команду pgrep:

pgrep bash***  1017 

Эта команда просто запросит идентификатор процесса и выведет его.

Процессу init, который создается первым при загрузке, присваивается PID “1”.

pgrep init***  1 

Этот процесс отвечает за создание всех остальных процессов в системе. Последующим процессам присваиваются большие номера PID.

Родитель процесса — это процесс, который отвечает за его создание. Родительские процессы имеют идентификатор PPID, который можно увидеть в заголовках столбцов многих приложений для управления процессами, включая top, htop и ps.

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

Отношения родительских и дочерних элементов

Создание дочернего процесса осуществляется в два этапа: fork() создает новое адресное пространство и копирует в него ресурсы, принадлежащие родительскому процессу, с помощью copy-on-write; а exec() загружает исполняемый блок в адресное пространство и выполняет его.

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

Отправка сигналов процессам в Linux

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

Отправка сигналов процессам по PID

Наиболее распространенный способ передачи сигналов в программу — использовать команду kill.

Как вы можете догадаться, по умолчанию эта утилита пытается уничтожить процесс:

<pre>kill <span class=“highlight”>PIDoftarget_process</span></pre>

Она отправляет процессору сигнал TERM. Сигнал TERM просит процесс остановиться. Это позволяет программе выполнить операции по очистке и нормально завершить работу.

Если программа работает неправильно и не завершает работу после получения сигнала TERM, мы можем отправить сигнал более высокого уровня — KILL:

<pre>kill -KILL <span class=“highlight”>PIDoftarget_process</span></pre>

Это специальный сигнал, который не отправляется программе.

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

Каждому сигналу присвоено число, которое можно передать вместо имени. Например, вы можете передать “-15” вместо “-TERM” и “-9” вместо “-KILL”.

Использование сигналов для других целей

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

Например, многие демоны перезапускаются при получении сигнала HUP или прекращения работы. Например, так работает Apache.

<pre>sudo kill -HUP <span class=“highlight”>pidofapache</span></pre>

Получив вышеуказанную команду, Apache перезагрузит файл конфигурации и возобновит вывод контента.

Вы можете вывести список сигналов, которые можно отправлять с помощью kill, используя следующую команду:

kill -l***  1) SIGHUP    2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP  6) SIGABRT  7) SIGBUS   8) SIGFPE   9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM . . . 

Отправка сигналов процессам по имени

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

Команда pkill работает практически точно так же как и kill, но использует имя процесса:

pkill -9 ping 

Вышеуказанная команда эквивалентна команде:

kill -9 `pgrep ping` 

Если вы хотите отправить сигнал каждому экземпляру определенного процесса, вы можете использовать команду killall:

killall firefox 

Приведенная выше команда отправит сигнал TERM всем экземплярам firefox, запущенным на этом компьютере.

Настройка приоритетов процессов

Часто бывает необходимо изменить приоритет процессов в серверной среде.

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

Linux контролирует приоритеты с помощью значения вежливости.

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

Когда мы запускали команду top в начале этого учебного модуля, мы видели столбец “NI”. В этом столбце отображается значение вежливости процесса:

top***   Tasks:  56 total,   1 running,  55 sleeping,   0 stopped,   0 zombie Cpu(s):  0.0%us,  0.3%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st Mem:   1019600k total,   324496k used,   695104k free,     8512k buffers Swap:        0k total,        0k used,        0k free,   264812k cached   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            1635 root      20   0 17300 1200  920 R  0.3  0.1   0:00.01 top                    1 root      20   0 24188 2120 1300 S  0.0  0.2   0:00.56 init                   2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd               3 root      20   0     0    0    0 S  0.0  0.0   0:00.11 ksoftirqd/0 

В зависимости от системы, значения вежливости могут различаться от “-19/-20” (наибольший приоритет) до “19/20” (наименьший приоритет).

Чтобы запустить программу с определенным значением вежливости, мы можем использовать команду nice:

<pre>nice -n 15 <span class=“highlight”>commandtoexecute</span></pre>

Это работает только в начале новой программы.

Чтобы изменить значение вежливости уже выполняемой программы, мы используем инструмент renice:

<pre>renice 0 <span class=“highlight”>PIDtoprioritize</span></pre>

Примечание. Хотя nice по необходимости использует имя команды, renice вызывает PID процесса.

Заключение

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

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

<div class=“author”>Джастин Эллингвуд</div>