В статье я покажу вам как осуществляется управление процессами в Linux. Вы узнаете про сигналы (kill), передний и задний фон (fg, bg, jobs), и приоритеты процессов (nice, renice). Управление процессами в Linux — это довольно обширная темя. Но все сводится к одному, мы различными способами меняем характеристики процессов. При этом мы можем преследовать совершенно разные цели: например мы можем хотеть завершить или приостановить процесс, поменять ему приоритет, заставить работать в фоне и другое.
🕒 8 мин.
Сигналы
Что такое сигналы
Все примеры в данной статье были сделаны в системе Debian 13, в других системах вывод может немного отличаться. Но работать всё должно похожим образом.
Сигналы нужны для асинхронного оповещения процессов о разнообразных событиях в системе. Это могут быть события оборудования или события других процессов. Работа сигналов очень похожа на прерывания. То есть, если процесс получает сигнал, то он прерывает свою обычную работу, обрабатывает сигнал, а затем продолжает работать.
Сигналы от ядра поступают процессам напрямую, а сигналы от одних процессов другим поступают через ядро с помощью системных вызовов. Системный вызов, который обрабатывает сигналы называется — kill(). Его так назвали, так как большинство стандартных сигналов «убивают» процессы.

Стандартные сигналы
Посмотреть обзор на сигналы можно выполнив man 7 signal, здесь вы можете посмотреть список стандартных сигналов:

Разберём некоторые из низ:
SIGHUP (1)— разрыв с управляющим терминалом. Процесс либо что-то предпримет (если программист об этом позаботился), либо завершится. Например, вы работаете с сервером, подключившись к нему по ssh, и вдруг связь пропадает, SSH сессия рвётся. Все ваши процессы неожиданно теряют управляющий терминал и начинают завершаться, так как получают от ядра этот сигнал.SIGINT (2)— клавиатурный сигнал, срабатывает когда мы нажимаем Ctrl+c. Это штатное завершение, то есть процесс будет завершён корректно (если он умеет завершаться корректно).SIGQUIT (3)— клавиатурный сигнал, срабатывает когда мы нажимаем Ctrl+\. Аварийное завершение с выдачей отладочной информации.SIGABRT (6)— аналогSIGQUIT (3). Если у процесса нет управляющего терминала, то отправить ему клавиатурный сигнал не получится, поэтому используется этот сигнал.SIGKILL (9)— этот сигнал сразу завершает процесс (некорректно).SIGTERM (15)— аналогSIGINT (2). Если у процесса нет управляющего терминала, то отправить ему клавиатурный сигнал не получится, поэтому используется этот сигнал.SIGTSTP (20)— клавиатурный сигнал, когда мы нажимаем Ctrl+z. Он приостанавливает процесс на управляющем терминале и переводит процесс в фон. Процесс переходит в состояние T (stopped by job control signal / остановленный специальным сигналом).
Команда kill
Команда kill позволяет отправлять сигналы процессам. В качестве параметров нужно указать номер сигнала (или имя) и PID процесса, например:
$ kill -9 9898 $ kill -SIGKILL 9898
Вы можете отправить сигнал своему процессу, а если хотите отправить чужому, то нужно использовать sudo.
Передний и задний фон
Когда вы работаете в графической системе, то вы можете одновременно работать в нескольких программах. Для этого используются окна приложений. Пока вы работаете с одной программой, её окошко работает на переднем плане. А в это время другие окна могут оставаться на заднем фоне (или просто в фоне).
Управление процессами в Linux можно применять и для того, чтобы в терминале можно было работать также, на переднем плане или в фоне. Представьте, что вы читаете справку man и захотели что-то попробовать. Чтобы не закрывать man, вы можете нажать Ctrl+z, при этом man приостановится и перейдет в фон.
$ man 7 signal (нажимаем Ctrl+z) [1]+ Остановлен man 7 signal
[1]— номер задания,+означает что это последнее приостановленное задание, дальше идёт состояние и название процесса.
Дальше вы можете поработать в терминале, а когда захотите, вернёте man на передний план.
$ jobs [1]+ Остановлен man 7 signal $ fg %1
- С помощью
jobs— смотрим список остановленных заданий. - С помощью
fg— возвращаем задание на передний план. Можно не указывать номер задания, тогда вернётся на передний план последнее приостановленное задание.
Запускаем процесс в фоне
Выше я показал как остановить процесс и поместить его в фон. Но в фоне процесс может быть не только в приостановленном состоянии а ещё и работать. Но только если выполнение процесса не требует от вас каких-то интерактивных действий (ввода или вывода).
То есть man запустить в фоне не получится. Попытаться можно, но он сразу вернётся в приостановленное состояние. Вот два сигнала, которые работают для фоновых заданий:
SIGTTIN (21)— остановлен за попытку чтения изstdin(в фоне).SIGTTOU(22)— остановлен за попытку вывода наstdout(в фоне).
А вот скачивание большого файла можно перевести в фон. Для этого нужно выполнить bg %<номер задания>.
$ wget https://releases.ubuntu.com/24.04/ubuntu-24.04.4-live-server-amd64.iso (нажимаем Ctrl+z) [2]+ Остановлен wget https://releases.ubuntu.com/24.04/ubuntu-24.04.4-live-server-amd64.iso $ bg %2 [2]+ wget https://releases.ubuntu.com/24.04/ubuntu-24.04.4-live-server-amd64.iso & alex@Copy-of-VM-debian-13:~$ Вывод перенаправляется в «wget-log».
wgetдолжен выводить информацию о скачивании файла, но в фоне это запрещено. Поэтому вывод автоматически перенаправляется в файл —wget-log.
С помощью ls можем убедиться что файл скачивается (его размер увеличивается):
$ ls -lh ubuntu-24.04.4-live-server-amd64.iso -rw-rw-r-- 1 alex alex 299M мар 24 10:32 ubuntu-24.04.4-live-server-amd64.iso $ ls -lh ubuntu-24.04.4-live-server-amd64.iso -rw-rw-r-- 1 alex alex 329M мар 24 10:32 ubuntu-24.04.4-live-server-amd64.iso
Отвязываем процесс от терминала
Если вы запустили долгоиграющий процесс на переднем плане, то можете перевести его работу в фон и отвязать от терминала. Затем можно будет закрыть терминал, не боясь что процесс завершится.
Делается это следующим образом.
- Останавливаем процесс (который работал не в фоне) нажатием
Ctrl+z. - Запускаем процесс в фоне командой
bg. - Чтобы отвязать процесс от терминала выполняем
disown %1.
Команда disown блокирует отправку системного сигнала SIGHUP (1).
Изменение приоритета процесса
Приоритеты процессов
В работающей системе Linux выполняется множество процессов, и каждому процессу назначается приоритет. Как ни странно, чем больше значение приоритета, тем меньше приоритет. То есть, процесс с приоритетом 15 будет более приоритетным, чем процесс с приоритетом 20.
Более приоритетные процессы получают больше процессорного времени. Они отзывчивее, быстрее, но при этом сильнее нагружают процессор и замедляют все остальные процессы.
Никакие пользователи (даже root) не могут управлять приоритетами процессов. Они могут управлять другим значением — nice. Диапазон nice имеет 40 приоритетов от -20 до +19. По умолчанию, любой процесс Linux, созданный пользователем, имеет значение nice = 0, и приоритет = 20.
Вы можете увидеть значение nice для процессов своего пользователя и своего терминала с помощью команды ps (её я рассматривал здесь):
$ ps -o pid,comm,nice,priority
PID COMMAND NI PRI
9631 bash 0 20
11187 man 0 20
11196 pager 0 20
11649 ps 0 20
Можно получить список всех процессов добавив опции ax:
$ ps ax -o pid,comm,nice,priority
PID COMMAND NI PRI
1 systemd 0 20
2 kthreadd 0 20
3 pool_workqueue_ 0 20
4 kworker/R-kvfre -20 0
5 kworker/R-rcu_g -20 0
6 kworker/R-sync_ -20 0
(вывод сократил)
Разница в том, что priority — это реальный приоритет процесса, а nice — подсказка для ядра указывающая нужно ли увеличить или уменьшить приоритет.
Для пользовательских процессов, в большинстве случаев, значение priority можно рассчитать по формуле: priority = 20 + nice.
Кроме ps, для просмотра приоритетов можно использовать top и htop.
Назначение приоритетов можно выполнять с помощью команд:
nice— настраивает приоритет процесса во время его запуска;renice— позволяет изменить приоритет уже запущенного процесса.
При этом:
- обычный пользователь может лишь уменьшить
niceсвоего процесса; - root может уменьшить или увеличить
niceсвоего или чужого процесса.
Команда nice
Вы можете проверить значение nice для своего терминала (оболочки), выполнив команду без аргументов:
$ nice 0
- Любые процессы запущенные в этой оболочки будут иметь
nice=0.
Чтобы запустить процесс с изменённым nice, его нужно запускать таким образом: nice <приоритет> <выполняемая команда>. Например, запустим две программы с разным приоритетом:
$ nice -2 md5sum /dev/urandom (нажимаем Ctrl+z) [2]+ Остановлен nice -2 md5sum /dev/urandom $ bg %2 [2]+ nice -2 md5sum /dev/urandom & $ nice -8 md5sum /dev/urandom (нажимаем Ctrl+z) [3]+ Остановлен nice -8 md5sum /dev/urandom $ bg %3 [3]+ nice -8 md5sum /dev/urandom & $ jobs [1]+ Остановлен man 7 signal [2] Запущен nice -2 md5sum /dev/urandom & [3]- Запущен nice -8 md5sum /dev/urandom &
Теперь, с помощью htop, посмотрим на процессы:
$ htop -u alex

Команды md5sum работают параллельно. Но у одной команды приоритет стал 22, а у другой 28. При этом более приоритетный процесс получает больше процессорного времени, это видно в колонке TIME+.
А если мы хотим указать отрицательное значение для nise, тем самым увеличив приоритет. То должны использовать двойное тире и sudo:
$ sudo nice --2 md5sum /dev/urandom (нажимаем Ctrl+z) [4]+ Остановлен sudo nice --2 md5sum /dev/urandom $ bg %4 [4]+ sudo nice --2 md5sum /dev/urandom &
Кстати, этот экземпляр md5sum, будет работать от пользователя root.
$ ps -C md5sum -o pid,user,comm,nice,priority,time,%cpu
PID USER COMMAND NI PRI TIME %CPU
11766 alex md5sum 2 22 00:07:14 90.4
11777 alex md5sum 8 28 00:06:08 87.0
11853 root md5sum -2 18 00:00:45 49.0
- Постепенно процесс с повышенным приоритетом получит больше процессорного времени, чем было у 2-ух предыдущих процессов.
Команда renice
Чтобы изменить приоритет уже работающего процесса нужно использовать команду renice -n <значение> -p <pid>. Этой командой может пользоваться только root.
Вернём всем процессам значение nice=0:
$ sudo renice -n 0 -p 11766
$ sudo renice -n 0 -p 11777
$ sudo renice -n 0 -p 11853
$ ps -C md5sum -o pid,user,comm,nice,priority,time,%cpu
PID USER COMMAND NI PRI TIME %CPU
11766 alex md5sum 0 20 00:10:17 86.0
11777 alex md5sum 0 20 00:07:13 65.7
11853 root md5sum 0 20 00:04:29 81.9
А ещё вы можете изменить приоритет всех процессов определённого пользователя таким образом: sudo renice -n <значение nice> -u <имя пользователя>.
$ sudo renice -n 5 -u alex
$ ps -C md5sum -o pid,user,comm,nice,priority,time,%cpu
PID USER COMMAND NI PRI TIME %CPU
11766 alex md5sum 5 25 00:10:46 84.5
11777 alex md5sum 5 25 00:07:44 65.5
11853 root md5sum 0 20 00:05:04 80.9
- Процессы alex стали с уровнем nice=5, а процесс root так и остался nice=0.
Итог
Статья получилось довольно длинной. Я показал как происходит некоторое управление процессами в Linux.
Рассказал про сигналы и как их отправлять процессам с помощью клавиатуры или с помощью команды kill. Также я показал, как можно использовать передний (fg) и задний (bg) фон терминала, и этим реально можно пользоваться. Также я разобрал приоритеты процессов и как их можно менять с помощью команд nice и renice.
В статье много примеров использования команды ps. Умение работать с этой утилитой, это очень полезный навык для системного администратора Linux.
Если понравилась статья, подпишись на мой канал в VK или Telegram.