Что такое зомби-процесс (zombie) в Linux?

«Что такое зомби-процесс (zombie) в Linux?» — вопрос из категории Linux, который задают на 29% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Зомби-процесс (zombie, defunct) — это процесс, который завершил своё выполнение (его код и ресурсы освобождены), но его запись остаётся в таблице процессов операционной системы. Это происходит потому, что родительский процесс ещё не прочитал статус завершения своего дочернего процесса с помощью системного вызова wait() или waitpid().

Ключевые характеристики зомби:

  • Не потребляет CPU и память: Код процесса и его данные уже освобождены. Зомби занимает только запись в таблице процессов (PID и минимальная метаинформация).
  • Не может быть "убит": Сигнал SIGKILL на зомби не действует, так как процесс уже мёртв.
  • Исчезает автоматически: Когда родительский процесс, наконец, вызывает wait(), ядро передаёт ему статус завершения и окончательно удаляет запись о зомби. Если родительский процесс завершается, все его зомби-поты «усыновляются» процессом init (PID 1), который периодически вызывает wait() и очищает их.

Проблема для DevOps: Большое количество зомби-процессов (тысячи) может исчерпать доступные PIDs в системе, что помешает созданию новых процессов. Это часто указывает на баг в родительском процессе, который не обрабатывает завершение своих потомков.

Как обнаружить зомби:

# Статус 'Z' в выводе ps означает зомби
$ ps aux | grep 'Z'
USER       PID  PPID  STAT COMMAND
appuser   4567  1234  Z    [defunct-process]

# Или с помощью top, посмотрев на количество зомби в заголовке
$ top
...
Tasks: 100 total,   1 running,  98 sleeping,   0 stopped,   1 zombie
...

Типичные причины и отладка:

  1. Родитель в бесконечном цикле или заблокирован и не доходит до вызова wait().
  2. Родитель неверно настроил обработчик сигнала SIGCHLD. По умолчанию этот сигнал уведомляет родителя о завершении потомка. Если родитель явно игнорирует сигнал (signal(SIGCHLD, SIG_IGN)), ядро сразу очищает дочерние процессы, не превращая их в зомби. Но если родитель установил свой обработчик и в нём нет вызова wait(), зомби будут накапливаться.
  3. Для отладки используйте strace -p <PPID> на родительском процессе, чтобы увидеть, делает ли он системные вызовы wait4 или waitpid.

Решение: Исправить код родительского процесса, чтобы он корректно ожидал завершения дочерних процессов. В крайнем случае, если родитель "сломан", перезапуск родительского процесса очистит всех его зомби.