← Назад к вопросам
Как может возникнуть зомби-процесс
2.0 Middle🔥 141 комментариев
#Linux и администрирование
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Зомби-процесс: определение и механизм возникновения
Зомби-процесс (zombie process) — это процесс, который завершил своё выполнение, но его запись всё ещё находится в таблице процессов, потому что родительский процесс не прочитал его статус выхода.
Как возникает зомби-процесс
Механизм:
- Дочерний процесс завершает работу (вызывает exit() или завершается с ошибкой)
- Операционная система переводит процесс в состояние "завершён", но не удаляет его из таблицы процессов
- ОС отправляет сигнал SIGCHLD родительскому процессу
- Критический момент: Если родитель не обработает сигнал SIGCHLD и не вызовет wait() или waitpid(), дочерний процесс остаётся в таблице в виде зомби
Простой пример на bash:
# Запустим фоновый процесс
sleep 100 &
pid=$!
# Немедленно завершим его
kill $pid
# Процесс станет зомби, если родитель не вызовет wait()
ps aux | grep defunct # увидим <defunct> статус
Пример на Python:
import subprocess
import time
# Создаём дочерний процесс
proc = subprocess.Popen(['sleep', '5'])
# Процесс завершится, но мы не вызовем wait()
time.sleep(10)
# В это время процесс будет зомби
# ps aux | grep sleep -> увидим <defunct>
Когда возникают зомби
- Завершение без обработки: Дочерний процесс завершился, но родитель не вызвал wait() или waitpid()
- Плохая обработка сигналов: Родитель установил SIG_IGN для SIGCHLD или вообще не обрабатывает сигналы
- Busy-loop: Родитель занят обработкой других задач и не проверяет статус дочерних процессов
Как исправить
Правильная обработка сигналов:
#!/bin/bash
# Функция для очистки зомби-процессов
cleanup() {
while wait -n 2>/dev/null; do
true
done
}
trap cleanup SIGCHLD
# Теперь дочерние процессы будут корректно очищены
sleep 100 &
sleep 50 &
wait # ждём все процессы
На Python:
import subprocess
import signal
import sys
import os
def sigchld_handler(signum, frame):
while True:
try:
pid, status = os.waitpid(-1, os.WNOHANG)
if pid == 0:
break
except ChildProcessError:
break
signal.signal(signal.SIGCHLD, sigchld_handler)
proc = subprocess.Popen(['sleep', '100'])
# процесс будет правильно очищен
Мониторинг зомби-процессов
# Найти все зомби-процессы
ps aux | grep defunct
# Более подробно
ps -eo ppid,pid,cmd,stat | grep -i defunct
# Узнать родителя зомби
ps -o ppid= -p <zombie_pid>