Зомби-процесс (Zombie, defunct process) — это уже завершенный процесс, который остается в таблице процессов до тех пор, пока его родитель не прочитает его статус завершения.
Ключевые характеристики:
Z
в ps
/top
SIGKILL
(уже мертв)Пример обнаружения:
ps aux | grep 'Z'
# Или более точно:
ps -eo pid,ppid,stat,cmd | grep -w 'Z'
exit()
или сигнал)wait()
или waitpid()
для чтения статусаwait()
→ процесс становится зомби#include <stdlib.h>
#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid == 0) {
// Дочерний процесс завершается сразу
exit(0);
} else {
// Родитель НЕ вызывает wait() и продолжает работу
sleep(30);
}
return 0;
}
Компиляция и запуск:
gcc zombie.c -o zombie
./zombie
# В другом терминале:
ps aux | grep 'Z'
Если родительский процесс явно игнорирует сигнал SIGCHLD
:
signal(SIGCHLD, SIG_IGN);
Пример на Python:
import os
import time
pid = os.fork()
if pid == 0:
# Дочерний процесс
os._exit(0)
else:
# Родитель не вызывает os.wait()
time.sleep(1000)
Утечка PID:
/proc/sys/kernel/pid_max
) нельзя создать новые процессыПроблемы мониторинга:
Признак проблем в приложении:
// Вариант 1: Блокирующий вызов
wait(NULL);
// Вариант 2: Неблокирующая проверка
while (waitpid(-1, NULL, WNOHANG) > 0);
void sigchld_handler(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0);
}
int main() {
signal(SIGCHLD, sigchld_handler);
// ...
}
ps -eo pid,ppid,stat,cmd | grep -w 'Z'
sudo kill -HUP 1
Ядро Linux автоматически очищает зомби, если:
signal(SIGCHLD, SIG_IGN)
)perl -e 'fork(); exit; sleep 10'
ps -eo pid,ppid,stat,cmd | grep -w 'Z'
kill -9 PPID_зомби
Резюмируем:
wait()
/waitpid()