Процесс это запущенная программа: память, открытые файлы, текущий каталог, переменные окружения и идентификатор PID. У каждого процесса есть родитель (PPID). Первый процесс в системе имеет PID 1, обычно это systemd.
Как рождается процесс: fork и exec
Новый процесс в Linux появляется в два шага:
fork()создаёт копию родителя. Память не копируется сразу: страницы общие до первой записи (copy-on-write).exec()заменяет программу в этой копии на другую. PID при этом не меняется.
Так работает shell: на команду ls он делает fork, в потомке exec ls, а сам ждёт завершения через wait(). Встроенные команды (cd, export) выполняются без fork, иначе они изменили бы только потомка.
Состояния процесса
В ps и top колонка STAT или S:
R: выполняется или готов к выполнению.S: спит и ждёт события, его можно прервать сигналом. Так выглядит большинство процессов.D: непрерываемый сон, обычно ожидание диска или NFS. Сигналы, дажеSIGKILL, подождут, пока операция не завершится.T: остановлен (Ctrl+ZилиSIGSTOP).Z: зомби.
Зомби и сироты
Когда процесс завершается, ядро хранит его код возврата, пока родитель не вызовет wait(). Такой завершённый, но не «прочитанный» процесс и есть зомби. Память он не ест, только запись в таблице процессов. Убить зомби нельзя, он уже мёртв. Лечат родителя: исправляют код, чтобы он ждал детей, или завершают родителя, тогда зомби усыновит PID 1 и приберёт.
Сирота это живой процесс, у которого умер родитель. Его усыновляет PID 1 (или ближайший процесс-«субрипер»). Это нормально.
Сигналы
Сигнал это асинхронное уведомление процессу. Главные:
| Сигнал | Номер | Смысл |
|---|---|---|
SIGHUP | 1 | обрыв терминала; демоны часто перечитывают конфиг |
SIGINT | 2 | Ctrl+C |
SIGQUIT | 3 | Ctrl+\, завершение с core dump |
SIGKILL | 9 | убить немедленно, нельзя перехватить |
SIGTERM | 15 | вежливая просьба завершиться, по умолчанию у kill |
SIGSTOP | 19 | остановить, нельзя перехватить |
SIGCONT | 18 | продолжить |
SIGCHLD | 17 | у потомка изменилось состояние |
Номера указаны для x86_64 и ARM. Правильный порядок остановки: сначала SIGTERM, дать время закрыть соединения и дописать данные, и только потом SIGKILL. kill -9 сразу лишает процесс шанса прибраться: остаются lock-файлы, недописанные данные, незакрытые транзакции.
kill 1234 # SIGTERM
kill -HUP 1234 # перечитать конфиг (если процесс это умеет)
kill -9 1234 # крайняя мера
pkill -f 'node server.js'
Код возврата процесса, убитого сигналом, в shell равен 128 + номер сигнала: 137 для SIGKILL, 143 для SIGTERM. Это пригодится при разборе OOMKilled в Kubernetes.
Смотрим процессы
ps aux # все процессы, BSD-стиль
ps -ef --forest # с родителями и деревом
ps -o pid,ppid,stat,rss,cmd -p 1234
pgrep -a nginx
cat /proc/1234/status # всё о процессе из ядра
ls -l /proc/1234/fd # открытые файлы
/proc/<pid> это окно в ядро: cmdline, environ, status (память, состояние, PPID), fd/, limits.
Фон, задачи и отвязка от терминала
cmd &запускает в фоне,jobsпоказывает задачи,fg %1иbg %1переключают.- При закрытии терминала shell рассылает
SIGHUP, и фоновые задачи умирают. Спасаютnohup cmd &,disown,setsidилиtmux/screen. - Для серверов правильный путь не
nohup, а юнит systemd: рестарты, логи, лимиты.
Приоритеты
nice от -20 (самый важный) до 19 (самый уступчивый). nice -n 10 backup.sh запускает с пониженным приоритетом, renice меняет на ходу. Повышать приоритет (отрицательный nice) может только root. Для диска есть ionice.
Частые ошибки
- Сразу
kill -9: процесс не успевает закрыть файлы и соединения. - Пытаться убить зомби. Надо разбираться с родителем.
- Путать
DиZ.Dжив и ждёт ввода-вывода, это признак проблем с диском или сетевой ФС. - Запускать сервис через
nohupв продакшене вместо systemd.
Что спросят на собесе
- Как создаётся процесс: fork, exec, copy-on-write.
- Что такое зомби и как от него избавиться.
- Чем SIGTERM отличается от SIGKILL, почему не стоит начинать с
kill -9. - Что значат состояния R, S, D, Z.
- Почему код выхода 137 и что он говорит.