Senior DevOps Technical Writer
Сервер Linux, как и любой другой компьютер, использует приложения. Компьютер рассматривает эти приложения как процессы.
Хотя Linux автоматически выполняет все скрытые низкоуровневые задачи жизненного цикла процесса, нам необходим способ взаимодействия с операционной системой для управления на более высоком уровне.
В этом учебном модуле мы расскажем о некоторых простых аспектах управления процессами. Linux предоставляет широкий выбор инструментов для этой цели.
В качестве примера мы используем Ubuntu 12.04 VPS, но любые современные дистрибутивы Linux будут работать аналогичным образом.
Чтобы посмотреть, какие процессы запущены на вашем сервере, нужно запустить команду 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 процессов находятся в режиме сна (т. е. не активны/не используют ресурсы ЦП).
В нижней части отображаются запущенные процессы и статистика их использования.
В репозиториях доступна улучшенная версия 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 здесь.
И 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 реагируют на сигналы. Операционная система использует сигналы, чтобы отправить программам команду остановиться или изменить поведение.
Наиболее распространенный способ передачи сигналов в программу — использовать команду kill
.
Как вы можете догадаться, по умолчанию эта утилита пытается уничтожить процесс:
<pre>kill <span class=“highlight”>PID_of_target_process</span></pre>
Она отправляет процессору сигнал TERM. Сигнал TERM просит процесс остановиться. Это позволяет программе выполнить операции по очистке и нормально завершить работу.
Если программа работает неправильно и не завершает работу после получения сигнала TERM, мы можем отправить сигнал более высокого уровня — KILL
:
<pre>kill -KILL <span class=“highlight”>PID_of_target_process</span></pre>
Это специальный сигнал, который не отправляется программе.
Вместо этого он передается в ядро операционной системы, которое отключает процесс. Он используется, чтобы обходить программы, игнорирующие отправляемые им сигналы.
Каждому сигналу присвоено число, которое можно передать вместо имени. Например, вы можете передать “-15” вместо “-TERM” и “-9” вместо “-KILL”.
Сигналы используются не только для отключения программ. Их также можно использовать для выполнения других действий.
Например, многие демоны перезапускаются при получении сигнала HUP
или прекращения работы. Например, так работает Apache.
<pre>sudo kill -HUP <span class=“highlight”>pid_of_apache</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”>command_to_execute</span></pre>
Это работает только в начале новой программы.
Чтобы изменить значение вежливости уже выполняемой программы, мы используем инструмент renice
:
<pre>renice 0 <span class=“highlight”>PID_to_prioritize</span></pre>
Примечание. Хотя nice по необходимости использует имя команды, renice вызывает PID процесса.
Управление процессами — это тема, которая иногда бывает сложной для новых пользователей, потому что используемые для этой цели инструменты отличаются от аналогичных инструментов с графическим интерфейсом.
Однако все эти идеи знакомы, интуитивно понятны и станут привычными после небольшой практики. Поскольку процессы используются в компьютерных системах повсеместно, умение эффективно управлять ими — критически важный навык.
<div class=“author”>Джастин Эллингвуд</div>
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!