Модуль 13. Процессы. Работа с процессами
Введение
Этот модуль расскажет об особенностях жизненного цикла процессов в Linux, об их рождении, жизни и смерти. Вы узнаете, что такое сигналы, для чего они нужны и как их использовать. Будет рассмотрена работа планировщика задач CFS и способы приоритизации процессов в Linux. Мы также научимся продвинутым приемам извлечения информации о процессах и управления ими.
Процессы и потоки в Linux
Основным назначением операционной системы, как мы знаем, является создание условий для работы прикладных приложений. Однако установленные в системе приложения — это всего лишь файлы, которые просто лежат на диске. Для того чтобы приложение «заработало», создается так называемый процесс.
При запуске программы операционная система выделяет экземпляру приложения независимое адресное пространство памяти, назначает уникальный идентификатор (Process Identifier, PID) и вносит запись в таблицу процессов. С этого момента планировщик задач (scheduler) начинает выделять процессу кванты процессорного времени, и программа оживает.
Процессы Linux и Windows во многом очень похожи, но есть и ряд отличий, понимание которых упростит работу с системой. Давайте разбираться.
Процессы в Linux и Windows
Дерево процессов в Linux
Приложение начинает работать, как только информация об экземпляре приложения заносится в таблицу процессов и планировщик начинает выделять ему кванты процессорного времени.
Для просмотра таблицы процессов в CMD мы использовали команду tasklist
, в PowerShell командлет Get-Process, а в Linux для этого предназначена утилита ps. И начнем мы с наиболее часто используемых ключей aux:
localadmin@astra:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 103172 11500 ? Ss 05:56 0:00 /sbin/init
root 2 0.0 0.0 0 0 ? S 05:56 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 05:56 0:00 [rcu_gp]
...
Назначение использованных нами ключей следующее:
a — отобразить процессы всех пользователей;
u — показать, кто является владельцем процесса;
x — показать процессы, у которых нет управляющего терминала, например, службы.
Внимание
Для обеспечения обратной совместимости Bash-скриптов утилита ps поддерживает ключи, используемые разными операционными системами: BSD (без дефисов), POSIX (c дефисами) и GNU (c двумя дефисами и длинными ключами). Поэтому короткие ключи, совпадая по написанию, могут иметь совершенно разный смысл, например, команды ps -a
и ps a
покажут совсем не одно и то же.
Еще интереснее пример с командой ps -aux
, когда перед группой ключей ставится символ дефиса. По правилам POSIX эта команда должна вывести все процессы для пользователя с именем «x», но т.к. такого пользователя не существует в системе, утилита понимает, что мы имели в виду «aux» без дефиса, и показывает нам этот результат.
Давайте с помощью ключей -ef
выведем ту же информацию, но с идентификатором родителя и поговорим об иерархии процессов в Linux:
localadmin@astra:~$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:41 ? 00:00:01 /sbin/init
root 2 0 0 09:41 ? 00:00:00 [kthreadd]
root 3 2 0 09:41 ? 00:00:00 [rcu_gp]
root 4 2 0 09:41 ? 00:00:00 [rcu_par_gp]
root 5 2 0 09:41 ? 00:00:00 [slub_flushwq]
root 6 2 0 09:41 ? 00:00:00 [netns]
root 8 2 0 09:41 ? 00:00:00 [kworker/0:0H-events_highpri]
...
Назначение использованных нами ключей следующее:
Ключ
-e
— отобразить процессы всех пользователей (то же самое, что ключ-a
);Ключ
-f
— вывести больше доступной информации, например, идентификатор родителя.
localadmin@astra:~$ ps aux
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 20:03 ? 00:00:00 /sbin/init
root 2 0 0 20:03 ? 00:00:00 [kthreadd]
root 3 2 0 20:03 ? 00:00:00 [rcu_gp]
...
Существенным отличием Windows и Linux является строгая иерархия процессов. В системе Windows дочерние процессы, конечно же, сохраняют идентификатор родителя, но система не следит за целостностью этой информации, и через некоторое время это значение может соответствовать несуществующему или неправильному процессу. Так происходит, если родительский процесс был закрыт, и этот идентификатор был повторно выдан другому процессу.
В системе Linux, напротив, установлена жесткая иерархия, поэтому описанная выше ситуация невозможна. Иерархический подход позволяет при закрытии терминала отправить всем дочерним процессам сигнал SIGHUP, чтобы закрыть их автоматически. Если же процесс был запущен через команду nohup
и нужно, чтобы он продолжил свою работу, то он станет «осиротевшим» и будет автоматически усыновлен процессом init (systemd) с PID=1.
Проведем эксперимент, который наглядно покажет разницу в поведении систем:
Если запустить приложение calc.exe из терминала cmd или PowerShell, то после закрытия терминала калькулятор продолжит работу как ни в чем ни бывало, что является вполне ожидаемым поведением.
Если же мы из терминала Gnome Terminator запустим калькулятор в фоновом режиме командой
kcalc &
и закроем окно терминала c помощью ALT + F4, а не через командуexit
, то терминал закроется вместе с калькулятором. А это уже ни разу не ожидаемое поведение.А теперь повторим то же самое в fly-term от Astra Linux и увидим, что терминал можно закрывать хоть крестиком, хоть через
exit
, а калькулятор остается на месте, как будто его запустили через nohup, что намного привычнее для Windows-администраторов. Ой, ну, что вы…что вы… даже не благодарите.
Используя значение PPID, мы можем легко найти все процессы, запущенные из текущей оболочки. При этом мы, конечно, можем поупражняться в составлении трехэтажных регулярных выражений, но проще будет воспользоваться специальной утилитой pgrep
и системной переменной $$, в которой содержится идентификатор текущего процесса. Команда в этом случае будет выглядеть так:
localadmin@astra:~$ ps -f -p$(pgrep --parent=$$)
UID PID PPID C STIME TTY STAT TIME CMD
localad+ 2322 1395 0 00:06 pts/0 Sl 0:00 kcalc
localad+ 2328 1395 0 00:06 pts/0 Sl 0:00 kcalc
localad+ 2334 1395 0 00:06 pts/0 Sl 0:00 kcalc
Возвращаясь к дереву процессов, обратим ваше внимание на то, что дерево, на самом деле, не одно, см. рис. 49. Чтобы убедиться в этом на практике, воспользуемся утилитой pstree
и выведем список всех потомков процесса с PID=0, которые были порождены ядром системы:
localadmin@astra:~$ pstree -p 0
?()─┬─kthreadd(2)─┬─acpi_thermal_pm(96)
│ ├─ata_sff(84)
│ ├─audit_prune_tre(367)
│ ├─blkcg_punt_bio(82)
...
│ ├─writeback(30)
│ └─zswap-shrink(125)
└─systemd(1)─┬─NetworkManager(474)─┬─{NetworkManager}(502)
│ └─{NetworkManager}(503)
├─VBoxClient(1232)───VBoxClient(1233)─┬─{VBoxClient}(1235)
│ └─{VBoxClient}(1236)
├─VBoxClient(1244)───VBoxClient(1245)─┬─{VBoxClient}(1247)
│ └─{VBoxClient}(1248)
├─VBoxClient(1251)───VBoxClient(1253)─┬─{VBoxClient}(1255)
│ ├─{VBoxClient}(1256)
│ └─{VBoxClient}(1257)
...
Процесс systemd или /sbin/init
является процессом подсистемы инициализации и управления службами systemd, которая пришла на замену устаревшей подсистеме init. Новая реализация обеспечила распараллеливание запуска служб, что позволило существенно ускорить загрузку ОС. В настоящий момент systemd полностью вытеснила init SysV, но файл /sbin/init
используется до сих пор и является символьной ссылкой на /lib/systemd/systemd
.
Процесс [kthreadd] является диспетчером потоков, а квадратные скобки указывают нам на то, что это процесс самого ядра ОС. Второе дерево потребовалось, потому что для управления потоками нельзя было использовать процесс systemd, который работает в пользовательском пространстве.
Адресное пространство
Как уже было сказано ранее, каждому процессу выделяется независимое адресное пространство памяти. Максимальный размер пространства в 64-битных системах в теории может доходить до 264B, а на практике для x86 процессоров не превышает 248B, т.е. до 256 ТБ (см. вывод команды cat /proc/cpuinfo
«address sizes … 48 bits virtual»). Но это все равно чуть больше, чем дохарда. Хотя, кто его знает… Биллу Гейтсу до сих пор припоминают его «640 КБ должно хватить всем».
Важно понимать, что размер адресного пространства и объем памяти, потребляемый процессом, — это две большие разницы. Все адресное пространство разбивается на страницы объемом в 4Кб (см. getconf PAGE_SIZE
), которых у процесса может быть, как у дурака фантиков. Однако большая часть этих страниц остается пустой, то есть не сопоставлена с реальной памятью компьютера, см. рис. 50:, поэтому процесс занимает ровно столько памяти, сколько он запросил, или как еще говорят «аллоцировал» (от англ. allocation – резервировать).
Обычно процессы могут аллоцировать весь доступный объем памяти, и ничего настраивать дополнительно не требуется. Выполните команду ulimit -a
, и вы увидите, что для «virtual memory» установлено значение «unlimited»:
localadmin@astra:~$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 15317
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 15317
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Однако бывают ситуации, когда мы сталкиваемся, например, с утечкой памяти, и, чтобы дожить до патча, устраняющего проблему, приходится подкручивать настройки. Например, с помощью команды ulimit -v 512000
мы можем ограничить потребление памяти процессами «на лету», а с помощью строки «* - as 512000» в конфигурационном файле /etc/security/limits.conf
выставить эти ограничения на постоянной основе.
Добавим еще, что из соображений безопасности адресные пространства процессов независимы друг от друга, поэтому один процесс не может напрямую получить доступ к переменным и структурам данных другого процесса. В тех случаях, когда это действительно требуется, процессы должны обмениваться информацией через механизмы межпроцессного взаимодействия (от англ. Inter-Process Communication, IPC).
Как вы помните, в Linux основными механизмами IPC являются файлы, каналы (pipe, fifo), сокеты (Unix и TCP/IP), сигналы, разделяемая память и др. В Windows есть аналогичные технологии каналов, TCP/IP сокетов, разделяемой памяти, но при организации межпроцессного взаимодействия в большей степени используются программные интерфейсы, такие как объектная модель компонентов (от англ. Component Object Model, COM) или удаленный вызов процедур (от англ. Remote Procedure Call, RPC). В том числе по этой причине Linux работает пошустрее.
Порождение процесса
В системе Linux новый процесс создается вызовом ядра fork(), во время выполнения которого происходит полное копирование адресного пространства родительского процесса, назначается собственный PID/PPID и обнуляется статистика выполнения в таблицах ОС. В ряде случаев этого бывает достаточно, но если требуется запустить другой программный код (например, выполнить ps из командной строки bash), то сразу после fork() следует еще один системный вызов execve(), см. рис. 51.
Существует целое семейство вызовов exeс* (см. справку man 3 exec
), которые отличаются набором параметров и логикой работы. Например, вызов execl() имеет дело со списком, а execv() c вектором. Но все они решают одну и ту же задачу, просто немного по-разному.
Важно понимать, что копирование процесса происходит чрезвычайно быстро, так как копируются не сами данные, а только список страниц памяти, где эти данные хранятся. На все эти страницы устанавливается отметка Copy-on-Write (COW), поэтому, как только одному из процессов требуется внести изменения, для него создается копия соответствующей страницы. В итоге fork() оказывается значительно быстрее, чем функция CreateProcess() из Win32 API, хотя на современных процессорах это уже не столь важно.
Понятное дело, что системные администраторы не всегда обладают навыками программирования, и подробности о вызовах fork() и execve() могут показаться вам излишними. Но мы очень часто сталкиваемся с упоминаниями этих функций в журналах отладки и трассировки, поэтому общие представления о работе этого механизма крайне полезны.
Завершение процесса
Процесс может завершить свою работу штатно, когда программный код полностью выполнил поставленную перед ним задачу, из-за непредвиденной ошибки или аварийно по требованию администратора, например, командой kill -9 $(pidof kcalc)
.
Вне зависимости от того, как завершился процесс, он освобождает все свои ресурсы и становится пустой записью в таблице процессов, в которой остается только статус завершения, необходимый родительскому процессу для корректной обработки результатов. Для того чтобы родитель поскорее вычитал статус, ему направляется сигнал SIGCHLD, но до тех пор, пока это не произойдет, запись будет оставаться в таблице, поэтому такие процессы называются «зомби» — процесс уже «умер», но еще не «погребён» и продолжает занимать идентификатор.
Проблема с неупокоенными процессами заключается в том, что количество идентификаторов PID в дистрибутивах Linux всегда ограничено. К примеру, в Astra Linux их по умолчанию может быть не больше 32 768 (см. вывод команды cat /proc/sys/kernel/pid_max
). Поэтому, когда такие зомби восстают регулярно и в большом количестве, наступает зомби-апокалипсис, и система перестает запускать новые процессы.
Зомби-процессы могут появляться как по причине зависания родительского процесса, так и в связи с ошибками в программном коде, но отправлять SIGKILL зомби-процессам совершенно бесполезно, ибо то, что мертво, умереть не может. Чтобы очистить систему от зомби, можно еще раз вручную направить сигнал SIGCHLD родительскому процессу с помощью команды kill -s SIGCHLD <PPID>
. Если же родительский процесс завис и по-прежнему отказывается хоронить зомби, следующим шагом будет удаление родительского процесса. И не забываем про «семь бед – один reset» — после перезагрузки ни один зомби точно не выживет.
Состояния процесса во время его существования
Жизненный цикл процесса предусматривает 5 основных состояний, см. рис. 52. Посмотреть текущее состояние можно с помощью команды ps aux
в колонке STAT:
R - готов (ready) или выполняется (running).
D - непрерываемое ожидание (uninterruptible sleep) - ожидание определенного события, чаще всего ожидания операции ввода-вывода.
S - прерываемое ожидание (interruptible sleep) - ожидание неопределенного события или сигнала.
T - остановка - процесс приостановлен, например, отладчиком.
Z - зомби (zombie) - завершен, но сигнал SIGCHLD не получен родителем.
Статусы готов и выполняется обозначаются одной буквой R, т.к. процесс получает кванты процессорного времени по сто раз в секунду, и эта информация не несет для пользователя никакой полезной информации.
Если процессу требуется доступ к устройству ввода-вывода (например, прочитать данные из файла), то без получения этих данных дальнейшее выполнение процесса будет невозможным, и процесс перейдет в состояние непрерываемого ожидания (D). Это ожидание называется непрерываемым, так как даже команда kill -9 pid
в таком состоянии не более, чем предложение «свернуть удочки», которое процесс может полностью проигнорировать.
Существует также прерываемое ожидание (S). Это состояние наступает, когда процесс завершил выполнение задач и ожидает следующих запросов. Например, вы открыли калькулятор, и окно приложения ожидает ваших указаний. Прерываемым это ожидание называется потому, что процесс в таком состоянии может быть завершен (убит) администратором. Это не всегда безопасно, особенно применительно к базам данных, хотя и возможно.
Отправкой сигнала SIGSTOP процесс может быть переведен в состояние остановлен (T), в котором он замирает до получения сигнала разморозки SIGCONT. Вы можете использовать это состояние для приостановки процесса, который начал потреблять слишком много ресурсов, чтобы спокойно проанализировать причины, не завершая работу приложения сигналом SIGKILL.
Все вышеперечисленные четыре состояния являются штатными для процесса, а пятое состояние зомби (Z) мы уже рассмотрели подробно выше. Оно возникает, когда процесс завершил работу, но родитель не вычитывает его результаты. В этом случае вы можете повторно отправить SIGCHLD родителю, завершить работу родителя или перезагрузить систему.
Потоки в Linux
Кроме вызова fork() существует также системный вызов clone(), который позволяет создавать процессы с разделяемым адресным пространством или так называемые потоки (англ. thread).
Потоки позволяют организовать параллельную обработку данных на нескольких ядрах вычислительного узла, что сильно повышает итоговую скорость выполнения задачи. Например, если у вас 4 ядра плюс гипертрейдинг, то вы можете архивировать данные в 8 потоков, что будет в 8 раз быстрее.
В зависимости от используемых флагов потоки могут обладать разными возможностями:
CLONE_VM — общее адресное пространство (любой из потоков может поменять страницы в памяти, и эти изменения будут видны всем потокам);
CLONE_FS — общие сведения о файловой системе (корневой и текущий каталоги, umask, права на создаваемые файлы и каталоги по умолчанию);
CLONE_FILES — общая таблица открытых файлов;
CLONE_SIGHAND — общая таблица обработчиков сигналов;
CLONE_PARENT — позволяет создавать сестринские процессы с тем же PPID, как у себя.
С точки зрения Linux управление процессами и потоками – это очень похожие задачи, поэтому и для работы с ними используются одни и те же инструменты. Например, команда ps -T -p <pid>
покажет вам все потоки указанного процесса.
Сигналы для процессов в Linux
Мы уже знаем о том, что сигналы предназначены для межпроцессного взаимодействия. Этот механизм напоминает системные прерывания, поэтому сигналы иногда называют еще мягкими или программными прерываниями. Однако, если системные прерывания обрабатываются ядром, то обработчик сигналов находится внутри приложения.
Для отправки сигналов из командной строки предназначена утилита kill
(от англ. убить). Название утилиты объясняется тем, что без дополнительных уточнений она отправляет сигнал SIGTERM, который как раз и означает завершение работы. Для того чтобы отправить какой-то другой сигнал, нужно указать цифровой код сигнала -<signal> или его имя с помощью ключа -s
(--signal
):
Запускаем калькулятор в фоновом режиме:
localadmin@astra:~$ kcalc &
[1] 5403
Завершаем процесс с выбранным PID 5403 из прошлой команды:
localadmin@astra:~$ kill -SIGTERM 5403
localadmin@astra:~$
Альтернативные варианты написания команды:
kill –TERM 5403
kill -15 5403
kill 5403
Процессы Linux поддерживают 64 сигнала, список которых можно посмотреть с помощью ключа -L
(-l
, --list
) команды kill
:
localadmin@astra:~$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
2) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
1) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
2) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
3) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
4) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
5) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
6) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
7) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
8) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
9) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
10) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
11) SIGRTMAX-1 64) SIGRTMAX
Чаще всего администраторы используют в работе сигналы:
Сигнал SIGINT(2) предназначен для прерывания работы приложений по требованию пользователя (от англ. interrupt — прервать) и отправляется автоматически активному процессу терминала по нажатию клавиш Ctrl + C.
Чаще всего администраторы отправляют этот сигнал приложениям через горячие клавиши, но можно сделать это и через утилиту kill. Продвинутые приложения могут реализовывать более сложную логику обработки этого сигнала, чем просто прерывание работы.
Например, Postgres запускает быстрое выключение: в этом случае сервер запрещает новые подключения и посылает всем процессам сигнал SIGTERM, в результате чего их транзакции прерываются, и сами процессы завершаются. Управляющий процесс ждёт, пока будут завершены все эти процессы и затем завершается сам.
Сигнал SIGKILL(9) требует процесс немедленно завершить свою работу. Процесс не имеет права проигнорировать этот сигнал и не может переопределить его обработчик, поэтому, если процесс не завершился по сигналу -9, то это указывает на какие-то проблемы в работе операционной системы. По своей сути сигнал SIGKILL похож на команду
End task
диспетчера задач Windows.Сигнал SIGTERM(15) отправляется процессу по умолчанию, если команде
kill
передать только идентификатор процесса. Сигнал просит процесс приступить к штатному завершению работы (от англ. software termination — завершение работы программного обеспечения).Если обработчик сигнала реализован в приложении правильно, то при получении SIGTERM процесс выполнит «умное выключение», т.е. обработает все несохраненные изменения, закроет файлы, сохранит состояние и вернет код 0, соответствующий успешному завершению.
При выключении операционной системы процессы сначала получают сигнал SIGTERM и только по таймауту завершаются принудительно.
Продвинутые администраторы расширяют набор своих инструментов сигналами:
Сигнал SIGHUP(1) посылается всем дочерним процессам терминала при его закрытии, чтобы они тоже завершили свою работу (от англ. hang up — повесить трубку). Название сигнала берет свое начало со времен аппаратных терминалов и телефонных линий связи.
Для того чтобы приложение игнорировало сигнал -1, его можно запустить с помощью команды
nohup
. Если закрыть терминал, такие процессы «осиротеют» и будут удочерены процессом init (systemd).
localadmin@astra:~$ kcalc &
[3] 20613
Приложение завершает свою работу:
localadmin@astra:~$ kill -SIGHUP 20613
localadmin@astra:~$ nohup kcalc &
Запускаем команду через nohup
:
localadmin@astra:~$ nohup kcalc &
[4] 20991
[3] Обрыв терминальной линии kcalc
Завершить процесс с помощью сигнала HUP больше не удается, он игнорируется приложением:
localadmin@astra:~$ kill -SIGHUP 20991
localadmin@astra:~$
Сигнал SIGCHLD(17) направляется родителю при завершении дочернего процесса. При появлении зомби-процессов сигнал может быть направлен вручную для обработки очереди.
Сигнал SIGSTOP(19) переводит процесс в состояние «остановлен», что удобно для отладки проблем с высоким потреблением ресурсов, когда требуется вернуть систему к жизни, не завершая проблемный процесс полностью. Процесс не имеет права проигнорировать этот сигнал и не может переопределить его обработчик. Для возобновления работы процесса предназначен сигнал SIGCONT.
Сигнал SIGTSTP(20) предназначен для остановки работы приложений из терминала (от англ. TTY stop) и отправляется автоматически активному процессу терминала по нажатию клавиш Ctrl + Z.
Сигнал SIGCONT(18) возобновляет работу процесса, который был остановлен с помощью сигналов SIGSTOP и SIGTSTP.
Каждый сигнал является указателем на область памяти, где находится обработчик, и многие из этих обработчиков могут быть переопределены внутри приложения через функцию trap(). Например, служба SSSD, обеспечивающая работу компьютера в домене, принимает сигналы SIGUSR2 и SIGUSR1 для того, чтобы переключиться в режим онлайн/офлайн соответственно:
admin@dc-1:~$ sudo kill -SIGUSR1 "$(pidof sssd)"
admin@dc-1:~$ sudo sssctl domain-status ald.company.lan
Online status: Offline
Active servers:
IPA: dc-1.ald.company.lan
Discovered IPA servers:
- dc-1.ald.company.lan
admin@dc-1:~$ sudo kill -SIGUSR2 "$(pidof sssd)"
admin@dc-1:~$ sudo sssctl domain-status ald.company.lan
Online status: Online
Active servers:
IPA: dc-1.ald.company.lan
Discovered IPA servers:
- dc-1.ald.company.lan
Планировщик задач в Linux и управление приоритетами процессов
Планировщик задач
Планировщик задач – это часть ядра ОС, необходимая для распределения ресурсов процессора между процессами. Планировщик преследует несколько целей:
Максимизировать пропускную способность, то есть количество задач, выполняемых за единицу времени.
Минимизировать время ожидания, то есть время, прошедшее с момента готовности процесса до начала его выполнения.
Минимизировать время ответа, то есть время, прошедшее с момента готовности процесса до завершения его выполнения.
Максимизировать равнодоступность, то есть справедливое распределение ресурсов между задачами.
Для достижения этих целей и обеспечения стабильности работы системы и приоритетного выполнения важных системных процессов используются системы приоритизации и распределения ресурсов по политикам планирования (группам процессов).
Группы процессов
В Linux существуют три основные группы процессов: First In, First Out (FIFO), Round Robin (RR) и Other. Первые две представляют собой процессы реального времени, которые должны выполняться немедленно, без задержек, а последняя, Other - условные процессы, при выполнении которых задержки не являются критичными для работы системы.
Таким образом, в системе существуют три очереди процессов, и логика выделения процессорного времени (логика выбора приоритета процесса) в каждой из них своя.
FIFO процессы (first in, first out, первый вошел, первый вышел) имеют самый высокий приоритет из всех. Такой процесс фактически работает в однопрограммном режиме и не реагирует ни на какие сигналы. Использование таких процессов несет серьезные риски, так как ошибка в его выполнении может критически повлиять на всю систему в целом.
В Linux используется всего несколько FIFO потоков ядра, для выполнения которых критически важно, чтобы их операции не прерывались и завершались без сбоев, например, изменение статуса процесса диспетчером процессов. В противном случае мы могли бы получить некорректную таблицу состояний процессов.
Процессы Round Robin (по круговой схеме) имеют более низкий приоритет по сравнению с FIFO процессами, поэтому при активизации FIFO процесса будут им вытеснены. Процессы RR равны между собой по приоритету в пределах одной очереди. Пока существует несколько процессов Round Robin. Каждому из них диспетчер выделяет определенный квант времени, и они будут выполняться по кругу, пока все такие процессы не будут завершены или не перейдут в состояния ожидания или остановки.
Процессы Other (все остальные) имеют самый низкий приоритет, то есть могут выполняться, только если нет активных FIFO или Round Robin процессов. В современных дистрибутивах Linux этими процессами занимается планировщик CFS (Completely Fair Scheduler, абсолютно справедливый планировщик), который старается соблюдать принцип справедливости, чтобы каждый процесс получил одинаковое количество процессорного времени. Кванты времени вычисляются так, чтобы исключить слишком частые переключения между процессами.
Отличительной особенностью планировщика CFS является высокая скорость сортировки процессов по потреблению ими процессорного времени за время log(N), так как для сортировки используется красно-черное дерево. Благодаря этому удалось добиться действительно справедливого распределения процессорного времени между процессами при высокой скорости самого планирования.
Политики планирования
Группы процессов FIFO, RR и Other соответствуют политикам планирования SCHED_FIFO, SCHED_RR и SCHED_OTHER (всего таких политик 6). Посмотреть список политик планирования можно командой chrt -m
.
localadmin@astra:~$ chrt -m
SCHED_OTHER min/max priority : 0/0
SCHED_FIFO min/max priority : 1/99
SCHED_RR min/max priority : 1/99
SCHED_BATCH min/max priority : 0/0
SCHED_IDLE min/max priority : 0/0
SCHED_DEADLINE min/max priority : 0/0
Как видим, выбор приоритета (а именно приоритета реального времени) доступен только в политиках SCHED_FIFO и SCHED_RR - от 1 до 99, для остальных политик он всегда 0.
Приоритет процессов
Каждому процессу присваивается приоритет. Это целое число от 39 до -100, где 39 - наименьший приоритет, а -100 - наивысший. Процессы с приоритетами от 39 до 0 - это обычные процессы из группы Other. Их приоритет не может быть меньше 0. По умолчанию все процессы из политики Other имеют приоритет 20, однако это значение может быть скорректировано как при запуске процесса (команда nice
), так и во время его работы (команда renice
). Эти команды меняют параметр NICE процессов - его «вежливость» (от англ. niceness), которая по умолчанию равна 0.
Параметр NICE может принимать значение от +19 до -20. При этом значение приоритета по умолчанию (20) суммируется со значением NICE, и, как упоминалось ранее, итоговый результат может принимать значение от 39 до 0.
Процессы с приоритетом от -1 до -100 - это процессы реального времени. У таких процессов кроме обычного приоритета существует приоритет реального времени, который используется в политиках планирования FIFO и RR. Для преобразования приоритета реального времени (rt_prior) в обычный приоритет процесса необходимо из -1 вычесть rt_prior. Например, при rt_prior равному 50, обычный приоритет будет равен -51 (-1 - 50 = -51).
Узнать текущее значение приоритета и параметра NICE можно в выводе команды htop
- колонки PRI и NI.
Задания, интерактивный и фоновый режимы работы процесса
Оболочка Bash позволяет останавливать работу процессов, переводить их в интерактивный и фоновый режим по ходу работы, для чего предназначено несколько команд.
Остановка процессов. Когда мы запускаем утилиты как обычно, например, kcalc
, они работают в интерактивном режиме, поэтому блокируют работу с терминалом. Если нам нужно вернуться к работе в терминале, мы можем закрыть приложение полностью клавишами Ctrl + C или временно приостановить его работу сочетанием Ctrl + Z. При этом калькулятор останется на экране, но перестанет реагировать на наши действия.
Перевод процесса в интерактивный режим. Когда мы захотим продолжить работу с калькулятором, нам нужно будет вернуть его обратно в интерактивный режим командой fg
. В этом случае калькулятор снова начнет реагировать на наши действия, но терминал опять окажется заблокирован.
Команда fg <задание>
переводит указанное задание в интерактивный режим (от англ. foreground — передний план). Задание может быть указано следующим образом:
<N> — порядковый номер задания, см. команду jobs далее.
%шаблон — поиск задания по его имени, например, %ping или %nmap.
%+ и %- — следующая и предыдущая задача.
%% — последняя задача. То же самое, что не указывать номер задания.
Перевод процесса в фоновый режим. Если же мы хотим продолжить работу с калькулятором, но не хотим терять доступ к терминалу, мы можем перевести приложение не в интерактивный, а в фоновый режим командой bg
. В этом случае нам будут доступны и калькулятор, и терминал одновременно, как будто калькулятор изначально был запущен командой kcalc &
с амперсандом на конце.
Команда bg <задание>
переводит указанное задание в фоновый режим (от англ. background — задний план). Задание задается таким же образом, как в команде fg
, поэтому не будем повторяться.
Просмотр фоновых заданий выполняется командой jobs
. У этой команды есть следующие ключи:
Ключ
-l
– выводит список процессов заданий с PID процесса и информацией по умолчанию.Ключ
-n
– выводит только те процессы, статус которых был изменен с последнего оповещения.Ключ
-p
– выводит список только PID фоновых процессов.Ключ
-r
– выводит только запущенные фоновые процессы.Ключ
-s
– выводит только остановленные фоновые процессы.
Давайте запустим три фоновых процесса и посмотрим список заданий:
localadmin@astra:~$ kcalc &
[1] 2514
localadmin@astra:~$ kcalc &
[2] 2523
localadmin@astra:~$ kcalc &
[3] 2531
localadmin@astra:~$ jobs
[1] Запущен kcalc &
[2]- Запущен kcalc &
[3]+ Запущен kcalc &
Извлечение информации о процессах
Информация о процессах доступна через псевдофайловую систему /proc
. Это универсальный интерфейс для доступа к данным о процессах и работе ядра ОС. Кроме того, используя определенные файлы, можно не только получать информацию о процессах, но и управлять некоторыми настройками ядра ОС. Утилиты для работы с процессами, такие как ps
, top
или htop
, в качестве источника информации используют как раз эту псевдофайловую систему.
Для пользователя взаимодействие с файлами /proc
выглядит как работа с обычными текстовыми файлами, но это совсем не так. Например, при чтении какого-либо файла командой cat
происходит системный вызов, и система формирует текстовый ответ, который передается команде.
Часть файлов предоставляет человекочитаемый формат данных, содержащих, например, пары ключ-значение, а часть – машиночитаемые, используемые при работе утилит, которые удобно использовать, например, в скриптах автоматизации.
Вначале мы разберем, что хранится в каталогах /proc/PID/
, где PID - числовой идентификатор процесса, например, /proc/1/
, а затем посмотрим содержимое самого каталога /proc/
.
Содержимое /proc/PID/
localadmin@astra:$ sudo ls /proc/1
arch_status fd numa_maps smaps_rollup
attr fdinfo oom_adj stack
autogroup gid_map oom_score stat
auxv io oom_score_adj statm
cgroup limits pagemap status
clear_refs loginuid patch_state syscall
cmdline map_files personality task
comm maps projid_map timens_offsets
coredump_filter mem root timers
cpu_resctrl_groups mountinfo sched timerslack_ns
cpuset mounts schedstat uid_map
cwd mountstats sessionid wchan
environ net setgroups
exe ns smaps
Файл /proc/cmdline
– в нем содержится строка запуска процесса.
localadmin@astra:~$ cat /proc/1/cmdline && echo
/sbin/init
Файл /proc/exe
– символическая ссылка, ведущая к полному пути до исполняемого файла. Полный путь необходим для однозначного понимания, какой именно файл был запущен.
localadmin@astra:~$ sudo ls -l --color=always /proc/1/exe
lrwxrwxrwx 1 root root 0 июл 18 11:32 exe -> /usr/lib/systemd/systemd
Файл /proc/cwd
– текущий рабочий каталог процесса PID1.
localadmin@astra:$ sudo ls -l --color=always /proc/1/cwd
lrwxrwxrwx 1 root root 0 июл 27 13:06 cwd -> /
Файл /proc/environ
– окружение процесса, создающее контекст его выполнения.
localadmin@astra:~$ sudo cat /proc/1/environ && echo
SHLVL=1HOME=/init=/sbin/initTERM=linuxBOOT_IMAGE=/boot/vmlinuz-5.15.0-33-genericdrop_caps=PATH=/sbin:/usr/sbin:/bin:/usr/binPWD=/rootmnt=/root
Каталог /proc/fd/
– дескрипторы открытых файлов (от англ. file descriptors). Каждый файл в fd/
представляет собой символическую ссылку и имеет числовое имя. Это не номер айноды в файловой системе, это уникальный номер в пределах процесса, который позволяет процессу обращаться к конкретным файлам, с которыми он работает. Дескрипторы 0, 1 и 2 - это стандартные ввод, вывод и вывод ошибок.
localadmin@astra:~$ sudo ls -l /proc/1/fd --color=always
итого 0
lrwx------ 1 root root 64 июл 18 11:32 0 -> /dev/null
lrwx------ 1 root root 64 июл 18 11:32 1 -> /dev/null
...
lrwx------ 1 root root 64 авг 4 09:03 109 -> 'socket:[20856]'
lr-x------ 1 root root 64 авг 4 09:03 11 -> anon_inode:inotify
...
lr-x------ 1 root root 64 авг 4 09:03 119 -> 'pipe:[16902]'
lr-x------ 1 root root 64 июл 18 11:32 12 -> /dev/autofs
lrwx------ 1 root root 64 авг 4 09:03 120 -> 'socket:[16920]'
lrwx------ 1 root root 64 авг 4 09:03 121 -> /run/initctl
lrwx------ 1 root root 64 авг 4 09:03 122 -> 'socket:[16904]'
lrwx------ 1 root root 64 авг 4 09:03 123 -> 'socket:[16906]'
lr-x------ 1 root root 64 авг 4 09:03 13 -> /proc/1/mountinfo
lr-x------ 1 root root 64 авг 4 09:03 14 -> anon_inode:inotify
lr-x------ 1 root root 64 авг 4 09:03 15 -> /proc/swaps
...
lrwx------ 1 root root 64 июл 18 11:32 2 -> /dev/null
lrwx------ 1 root root 64 июл 18 11:32 20 -> 'socket:[27113]'
...
Файл /proc/io
– содержит сведения об объемах данных, прочитанных и записанных процессом в хранилище информации.
localadmin@astra:~$ sudo cat /proc/1/io
rchar: 11296824165
wchar: 159986595
syscr: 6481108
syscw: 467703
read_bytes: 801298432
write_bytes: 258985984
cancelled_write_bytes: 43184128
Файл /proc/limits
– отображает различные ограничения процесса, установленные конфигурационным файлом /etc/security/limits.conf
и командой ulimit
.
localadmin@astra:~$ sudo cat /proc/1/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 7523 7523 processes
Max open files 1048576 1048576 files
Max locked memory 67108864 67108864 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 7523 7523 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
Файл /proc/maps
– физические адреса страниц памяти, используемые в данный момент.
localadmin@astra:~$ sudo cat /proc/1/maps | head
5e9ee4066000-5e9ee4094000 r--p 00000000 08:01 657629 /usr/lib/systemd/systemd
5e9ee4094000-5e9ee41af000 r-xp 0002e000 08:01 657629 /usr/lib/systemd/systemd
5e9ee41af000-5e9ee4204000 r--p 00149000 08:01 657629 /usr/lib/systemd/system
...
Файл /proc/pagemap
для каждой виртуальной страницы определяет её фактическое положение: в физической памяти или в файле подкачки. Информация хранится в двоичном коде.
Файл /proc/sched
–отображение текущих значений переменных планировщика процессов, необходимых для корректной работы планировщика SFC.
localadmin@astra:~$ sudo cat /proc/1/sched
systemd (1, #threads: 1)
se.exec_start : 1290085360.092074
se.vruntime : 11829.729715
se.sum_exec_runtime : 21150.129581
se.nr_migrations : 2199
nr_switches : 39002
nr_voluntary_switches : 29552
nr_involuntary_switches : 9450
se.load.weight : 1048576
se.avg.load_sum : 285
se.avg.runnable_sum : 291840
se.avg.util_sum : 271360
se.avg.load_avg : 0
se.avg.runnable_avg : 0
se.avg.util_avg : 0
se.avg.last_update_time : 1290085360091136
se.avg.util_est.ewma : 7
se.avg.util_est.enqueued : 0
uclamp.min : 0
uclamp.max : 1024
effective uclamp.min : 0
effective uclamp.max : 1024
policy : 0
prio : 120
clock-delta : 95
mm->numa_scan_seq : 0
numa_pages_migrated : 0
numa_preferred_nid : -1
total_numa_faults : 0
current_node=0, numa_group_id=0
numa_faults node=0 task_private=0 task_shared=0 group_private=0 group_shared=0
Файлы /proc/stat
и /proc/status
– близкие по своей сути, отражают основные сведения о процессе. Файл stat - машиночитаемый формат, а status - человекочитаемый. Большинство параметров, выводимых утилитой ps
, она получает из структур данных, аналогичных тем, которые отображаются в этих файлах.
localadmin@astra:~$ sudo cat /proc/1/stat
1 (systemd) S 0 1 1 0 -1 4194560 111979 3580285 170 48914 1384 733 32339 27124 20 0 1 0 11
1056563202873 18446744073709551615 104036523655168 104036524814201 140723869122320 0 0 0
671173123 4096 12601 0 0 17 0 0 0 0 0 0 104036525166288 104036525396288 104036533329920
140723869130571 140723869130582 140723869130582 140723869130733 0
localadmin@astra:/proc/1$ sudo cat status
Name: systemd
Umask: 0000
State: S (sleeping)
Tgid: 1
Ngid: 0
Pid: 1
PPid: 0
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 128
Groups:
NStgid: 1
NSpid: 1
NSpgid: 1
NSsid: 1
VmPeak: 168716 kB
VmSize: 103180 kB
...
Mems_allowed_list: 0
voluntary_ctxt_switches: 29574
nonvoluntary_ctxt_switches: 9459
Файл statm - статистика по использованию памяти. Это 7 чисел, из которых только 5 имеют значения в современных версиях ядра. Все значения - количество страниц памяти:
1 – общий размер памяти, занимаемой программой (то же, что и VmSize в файле status)
2 – размер резидентной памяти (то же, что и VmRSS в файле status)
3 – разделяемые страницы памяти (то же, что и RssFile+RssShmem в файле status)
4 – размер сегмента, отведенного под код
5 – не используется (всегда 0, начиная с ядра 2.6)
6 – размер сегмента данных и стека
7 – не используется (всегда 0, начиная с ядра 2.6)
localadmin@astra:~$ cat /proc/1/statm
25795 2873 2179 283 0 4927 0
Содержимое /proc
Ниже представлено содержимое каталога /proc/
. В выводе команды все каталоги с PID заменены на {PID 1,2,…,N} для лучшего восприятия. Файлы, хранящиеся в корне каталога /proc/
, характеризуют состояние и характеристики всего вычислительного узла и ядра ОС.
localadmin@astra:~$ ls /proc
{PID 1,2, … N}
asound irq schedstat bootconfig kallsyms scsi
buddyinfo kcore self bus keys slabinfo
cgroups key-users softirqs cmdline kmsg stat
consoles kpagecgroup swaps cpuinfo kpagecount sys
crypto kpageflags sysrq-trigger devices loadavg sysvipc
diskstats locks thread-self dma mdstat timer_list
driver meminfo tty dynamic_debug misc uptime
execdomains modules version fb mounts version_signature
filesystems mtrr vmallocinfo fs net vmstat
interrupts pagetypeinfo zoneinfo iomem partitions
ioports pressure
Файл /proc/cmdline
– список параметров, которые были переданы ядру при загрузке.
localadmin@astra:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-5.15.0-33-generic root=UUID=1864fbac-4e75-42ec-9a52-c0944d4fd6b9 ro parsec.mac=0 quiet net.ifnames=0
Файл /proc/cpuinfo
– сведения о всех установленных процессорах.
localadmin@astra:~$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 79
model name : Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz
stepping : 1
cpu MHz : 2394.456
cache size : 35840 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 2
...
Файл /proc/diskstats
– статистика операций со всеми дисками. Для каждого диска своя строка. Описание полей доступно по ссылке.
localadmin@astra:~$ cat /proc/diskstats
7 0 loop0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
. . .
8 1 sda1 44186 11778 2356130 13854 240755 305673 4556040 132537 0 336236 146391 0 0 0 0 0 0
8 2 sda2 2 0 4 0 0 0 0 0 0 8 0 0 0 0 0 0 0
8 5 sda5 69 0 5000 22 0 0 0 0 0 68 22 0 0 0 0 0 0
11 0 sr0 33 0 160 11 0 0 0 0 0 44 11 0 0 0 0 0 0
Файл /proc/meminfo
– отображение информации о состоянии памяти. Предоставляет больше параметров, чем утилита free.
localadmin@astra:~$ free
total used free shared buff/cache available
Mem: 4007624 448304 1761592 27816 1797728 3284820
Swap: 998396 0 998396
localadmin@astra:~$ cat /proc/meminfo
MemTotal: 2025208 kB
MemFree: 88064 kB
MemAvailable: 1295928 kB
Buffers: 181228 kB
Cached: 1101408 kB
SwapCached: 0 kB
Active: 1024936 kB
Inactive: 596484 kB
...
Файл /proc/devices
– перечень устройств в системе.
localadmin@astra:~$ cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
...
Block devices:
2 fd
7 loop
8 sd
9 md
11 sr
65 sd
66 sd
67 sd
...
Файл /proc/filesystem
– перечень файловых систем, поддерживаемых ядром ОС.
localadmin@astra:~$ cat /proc/filesystems
nodev sysfs
nodev tmpfs
nodev bdev
nodev proc
...
ext3
ext2
ext4
...
Файл /proc/mounts
– перечень смонтированных файловых систем (формат данных, аналогичен файлу /etc/fstab).
localadmin@astra:~$ cat /proc/mounts
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
udev /dev devtmpfs rw,nosuid,relatime,size=963080k,nr_inodes=240770,mode=755,inode64 0 0
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=202524k,mode=755,inode64 0 0
/dev/sda1 / ext4 rw,relatime,errors=remount-ro 0 0
parsecfs /parsecfs parsecfs rw,sync,relatime 0 0
securityfs /sys/kernel/security securityfs
rw,nosuid,nodev,noexec,relatime 0 0
tmpfs /dev/shm tmpfs rw,nosuid,nodev,inode64 0 0
Файл /proc/modules
– список подгруженных модулей ядра. Ядро Linux монолитное, но модульное, и мы можем управлять тем, какие модули подгружать, а какие нет, тем самым определяя функционал запускаемой ОС.
localadmin@astra:~$ cat /proc/modules
binfmt_misc 24576 1 - Live 0x0000000000000000 (E)
vboxvideo 36864 0 - Live 0x0000000000000000 (OE)
drm_ttm_helper 16384 1 vboxvideo, Live 0x0000000000000000 (E)
intel_rapl_msr 20480 0 - Live 0x0000000000000000 (E)
intel_rapl_common 32768 1 intel_rapl_msr, Live 0x0000000000000000 (E)
Файл /proc/swaps
– список разделов подкачки.
localadmin@astra:~$ cat /proc/swaps
Filename Type Size Used Priority
/dev/sda5 partition 998396 0 -2
Файл /proc/version
– версия ядра ОС.
localadmin@astra:~$ cat /proc/version
Linux version 5.15.0-33-generic (builder@build5) (gcc (AstraLinuxSE 8.3.0-6) 8.3.0, GNU ld (GNU Bin utils for AstraLinux) 2.31.1) #astra2+ci96 SMP Fri Oct 28 18:23:37 UTC 2
Каталог /sys/kernel/
содержит набор файлов, которые позволяют нам оперативно без перезагрузки изменять параметры ядра ОС (но таких параметров не очень много). Поэтому часть файлов в этом каталоге доступна для записи, и через эти интерфейсы мы можем управлять ядром. Некоторые из них будут рассмотрены в модуле, посвящённом ядру ОС.
localadmin@astra:~$ ls /proc/sys/kernel/
acct ngroups_max sched_energy_aware
acpi_video_flags nmi_watchdog sched_rr_timeslice_ms
auto_msgmni ns_last_pid sched_rt_period_us
bootloader_type numa_balancing sched_rt_runtime_us
bootloader_version oops_all_cpu_backtrace sched_schedstats
bpf_stats_enabled osrelease sched_util_clamp_max
cad_pid ostype sched_util_clamp_min
cap_last_cap overflowgid sched_util_clamp_min_rt_default
...
Управление процессами
Для управления процессами в Linux существует набор утилит. Рассмотрим работу с основными из них: консольными утилитами (ps
, top
и htop
, kill
), а для графической (системный монитор).
Управление процессами через консольные утилиты
Просмотр процессов
Для просмотра процессов есть три основные консольные утилиты (ps
, top
и htop
) и одна графическая (системный монитор). Утилита ps позволяет получить снимок текущего состояния всех или заданных процессов и их параметров.
localadmin@astra:~$ ps
PID TTY TIME CMD
23526 pts/4 00:00:19 bash
32038 pts/4 00:00:00 ps
Просмотр процессов через утилиты top и htop
Утилиты top
и htop
позволяют просматривать загрузку системы и процессы в реальном времени, изменять сортировку, набор и вид отображаемых параметров, менять значение nice
процессов или завершать процессы.
Основное отличие между ними в интерфейсе: htop
более удобен для новичков и тех, кто работал с Windows Task Manager. Он поддерживает управление мышью и имеет более «дружелюбный» интерфейс управления.
В нижней части экрана расположена подсказка про доступные действия с помощью функциональных клавиш. Например, при нажатии F2 мы попадем в меню настроек.
В меню Columns нам доступен выбор отображаемых столбцов и их описание.
Через клавишу F1 нам доступна кратка справка. Полная справка доступна через man htop.
Утилита ps
Почти все те же действия можно выполнять и с помощью утилиты ps, но без удобного интерактивного режима. Вот некоторые её опции:
-e
– вывести на дисплей процессы всех пользователей. Не отображаются только процессы, не связанные с терминалом.-a
– вывести информацию обо всех процессах, за исключением лидеров сессий и процессов, не ассоциированных с терминалом.-t
– показывать только процессы из этого терминала.-p
– показывать информацию только об указанном процессе.-u
– вывод подробной информации в пользовательско-ориентированном формате.-x
– показать процессы без управляющего терминала.-o
– задать формат вывода информации.
Таким образом, команда ps aux
выводит все активные процессы.
Для сортировки процессов можно воспользоваться параметром --sort
, например, ps aux --sort=%mem
или ps aux --sort=%cpu
.
localadmin@astra:~$ ps aux --sort=%mem | tail -n 3
localad+ 1866 0.0 1.7 565016 68348 ? Ssl 12:30 0:00 nm-applet
localad+ 1868 0.0 2.7 1524876 111060 ? Ssl 12:30 0:00 fly-sound-applet
root 778 0.0 3.1 912424 125044 tty7 Ssl+ 09:41 0:08 /usr/lib/xorg/Xorg
...
Команда ps -eo euser,ruser,suser,fuser,f,comm,label
выведет информацию об атрибутах EUID, RUID, SUID.
localadmin@astra:~$ ps -eo euser,ruser,suser,fuser,f,comm,label
EUSER RUSER SUSER FUSER F COMMAND LABEL
root root root root 4 systemd 0:0:0:0
root root root root 1 kthreadd 0:0:0:0
...
localad+ localad+ localad+ localad+ 4 systemd 0:0:0:0
localad+ localad+ localad+ localad+ 5 (sd-pam) 0:0:0:0
localad+ localad+ localad+ localad+ 4 fly-wm 0:0:0:0
...
С помощью утилиты ps можно посмотреть и потоки. Воспользуйтесь командами ps -eLf
и ps axms
.
localadmin@astra:~$ ps -eLf
UID PID PPID LWP C NLWP STIME TTY TIME CMD
root 1 0 1 0 1 фев22 ? 00:00:08 /sbin/init
. . .
localad+ 1493 1411 1493 0 1 фев22 pts/2 00:00:00 /bin/bash
root 15418 1 15418 0 11 фев26 ? 00:00:29 /usr/sbin/syslog-ng -F --no-caps
root 15418 1 15430 0 11 фев26 ? 00:00:00 /usr/sbin/syslog-ng -F --no-caps
root 15418 1 15431 0 11 фев26 ? 00:00:00 /usr/sbin/syslog-ng -F --no-caps
root 15418 1 19949 0 11 00:01 ? 00:00:00 /usr/sbin/syslog-ng -F --no-caps
root 15418 1 19950 0 11 00:01 ? 00:00:00 /usr/sbin/syslog-ng -F --no-caps
root 15418 1 19951 0 11 00:01 ? 00:00:00 /usr/sbin/syslog-ng -F --no-caps
root 15418 1 19952 0 11 00:01 ? 00:00:00 /usr/sbin/syslog-ng -F --no-caps
root 15418 1 19953 0 11 00:01 ? 00:00:00 /usr/sbin/syslog-ng -F --no-caps
root 15418 1 19954 0 11 00:01 ? 00:00:00 /usr/sbin/syslog-ng -F --no-caps
root 15418 1 19955 0 11 00:01 ? 00:00:02 /usr/sbin/syslog-ng -F --no-caps
root 15418 1 19957 0 11 00:01 ? 00:00:06 /usr/sbin/syslog-ng -F --no-caps
localad+ 17557 1468 17557 0 1 фев26 pts/0 00:00:00 man sudoedit
localad+ 17568 17557 17568 0 1 фев26 pts/0 00:00:00 pager
...
localadmin@astra:~$ ps axmu
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.5 168924 11548 ? - фев22 0:08 /sbin/init
root - 0.0 - - - - Ss фев22 0:08 -
. . .
localad+ 1493 0.0 0.2 7856 4592 pts/2 - фев22 0:00 /bin/bash
localad+ - 0.0 - - - - Ss+ фев22 0:00 -
root - 0.0 - - - - Ssl фев26 0:29 -
root - 0.0 - - - - Ssl фев26 0:00 -
root - 0.0 - - - - Ssl фев26 0:00 -
root - 0.0 - - - - Ssl 00:01 0:00 -
root - 0.0 - - - - Ssl 00:01 0:00 -
root - 0.0 - - - - Ssl 00:01 0:00 -
root - 0.0 - - - - Ssl 00:01 0:00 -
root - 0.0 - - - - Ssl 00:01 0:00 -
root - 0.0 - - - - Ssl 00:01 0:00 -
root - 0.0 - - - - Ssl 00:01 0:02 -
root - 0.0 - - - - Ssl 00:01 0:06 -
localad+ 17557 0.0 0.2 7288 4248 pts/0 - фев26 0:00 man sudoedit
localad+ - 0.0 - - - - S+ фев26 0:00 -
localad+ 17568 0.0 0.0 5592 904 pts/0 - фев26 0:00 pager
localad+ - 0.0 - - - - S+ фев26 0:00 -
...
Утилита pstree
С помощью утилиты pstree
можно вывести дерево процессов. Для её использования необходим пакет psmisc sudo apt install psmisc
.
localadmin@astra:~$ pstree
systemd─┬─3*[VBoxClient───VBoxClient───3*[{VBoxClient}]]
├─VBoxClient───VBoxClient───4*[{VBoxClient}]
├─VBoxDRMClient───4*[{VBoxDRMClient}]
├─VBoxService───8*[{VBoxService}]
├─agetty
├─alsactl
├─astra-orientati───2*[{astra-orientati}]
├─at-spi2-registr───2*[{at-spi2-registr}]
├─auditd───{auditd}
├─avahi-daemon───avahi-daemon
├─cron
├─cupsd
├─2*[dbus-daemon]
├─dbus-launch
├─dhclient───{dhclient}
├─fly-dm─┬─Xorg───{Xorg}
│ └─fly-dm───fly-wm─┬─astra-event-wat───{astra-event-wat}
│ ├─at-spi-bus-laun─┬─dbus-daemon
│ │ └─3*[{at-spi-bus-laun}]
│ ├─baloo_file───2*[{baloo_file}]
│ ├─fly-cups-watch───{fly-cups-watch}
│ ├─fly-notify-osd-───3*[{fly-notify-osd-}]
│ ├─fly-reflex-serv───3*[{fly-reflex-serv}]
│ ├─fly-search-pane───3*[{fly-search-pane}]
│ ├─fly-sound-apple───9*[{fly-sound-apple}]
│ ├─kscreend───2*[{kscreend}]
│ ├─nm-applet───3*[{nm-applet}]
│ ├─org_kde_powerde───6*[{org_kde_powerde}]
│ ├─polkit-kde-auth───4*[{polkit-kde-auth}]
│ ├─ssh-agent
│ └─x-terminal-emul─┬─bash───man───pager
│ ├─bash───htop
│ ├─2*[bash]
│ ├─bash───pstree
│ └─2*[{x-terminal-emul}]
├─fly-getexe
...
Ключ -p
позволяет вывести PID процессов pstree -p
.
localadmin@astra:~$ pstree -p
systemd(1)─┬─VBoxClient(1265)───VBoxClient(1266)─┬─{VBoxClient}(1267)
│ ├─{VBoxClient}(1268)
│ └─{VBoxClient}(1269)
├─VBoxClient(1280)───VBoxClient(1281)─┬─{VBoxClient}(1283)
│ ├─{VBoxClient}(1284)
...
Поиск процессов
Утилита htop
Для поиска процессов в htop необходимо воспользоваться пунктом Search. Для этого нажмите клавишу F3. Вам станет доступна строка поиска. После выполнения поиска вы можете переходить от одного процесса к другому. Для выхода из режима поиска нажмите клавишу Esc.
В целях поиска может использоваться и фильтрация. Она доступна по нажатию клавиши F4.
Для очистки фильтра нажмите клавишу Esc.
Утилита ps
Для фильтрации вывода команды ps
используйте встроенные опции: -123
или 123
, -p "1 2"
– вывод информации по PID процессу(ам).
localadmin@astra:~$ ps -1
PID TTY STAT TIME COMMAND
1 ? Ss 0:08 /sbin/init
localadmin@astra:~$ ps 1
PID TTY STAT TIME COMMAND
1 ? Ss 0:08 /sbin/init
localadmin@astra:~$ ps -p "1 2"
PID TTY TIME CMD
1 ? 00:00:08 systemd
2 ? 00:00:00 kthreadd
-С <имя_команды>
– вывод информации по процессам, имя команды которых соответствует указанному, например, ps -C bash
.
localadmin@astra:~$ ps -C bash
PID TTY TIME CMD
1468 pts/0 00:00:00 bash
1486 pts/1 00:00:00 bash
1493 pts/2 00:00:00 bash
Используя опцию -o pid, можно вывести только колонку с PID найденных процессов, а используя -o pid=, только PID без названия колонки.
localadmin@astra:~$ ps -C bash -o pid
PID
1468
1486
1493
localadmin@astra:~$ ps -C bash -o pid=
1468
1486
1493
Другие опции фильтрации ps в справке man 1 ps
.
Для дополнительной фильтрации можно использовать утилиту grep, например, ps aux | grep tty
.
localadmin@astra:~$ ps aux | grep tty
root 753 0.0 0.0 5612 1656 tty1 Ss+ 09:41 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
root 778 0.0 3.1 912424 125044 tty7 Ssl+ 09:41 0:08 /usr/lib/xorg/Xorg -br -novtswitch -quiet -keeptty :0 vt7 -seat seat0 -auth /var/run/xauth/A:0-ZTNgnb
localad+ 4933 0.0 0.0 6096 872 pts/0 S+ 18:11 0:00 grep tty
Завершение процессов
При работе с утилитой htop для отправки сигнала процессу необходимо нажать F9. По умолчанию будет выбран сигнал SIGTERM. Для завершения процесса с этим сигналом необходимо нажать F9 и Enter (или перед нажатием Enter вы можете выбрать по необходимости другой сигнал).
Управление через графику в Системном мониторе
Системный монитор напоминает «Менеджер задач» в Windows, что было сделано специально для удобства пользователей и администраторов. Он имеет интуитивно понятный интерфейс и не должен вызвать сложностей при своем использовании.
Управление доступно через контекстное меню и органы управления. Для поиска процессов доступна строка быстрого поиска, для завершения процесса – соответствующая кнопка над списком задач. С помощью выпадающих списков вы можете отфильтровать процессы по категориям.
В контекстном меню процесса можно перейти к окну этого приложения, вывести подробную информацию о процессе, перейти к родительскому процессу, отправить сигнал процессу или изменить его приоритет.
С подробной справкой вы можете ознакомиться в справочной системе Alt + F1.
Практика и тестирование
Заключение
В этом модуле мы узнали, что такое процессы и как устроен их жизненный цикл. Мы научились просматривать информацию о процессах и управлять ими. Теперь мы знаем, что такое зомби процессы и почему их не нужно бояться. Следующий модуль будет не настолько сложным. В нем мы познакомимся с вопросами архивирования.