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

«Что такое зомби-процесс (zombie process) в Unix-системах?» — вопрос из категории DevOps, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Зомби-процесс (Zombie или Defunct process) — это дочерний процесс в Unix-подобных системах, который завершил своё выполнение (с помощью exit()), но его запись остаётся в таблице процессов до тех пор, пока родительский процесс не прочитает его статус завершения.

Механизм возникновения:

  1. Дочерний процесс завершается.
  2. Ядро освобождает его ресурсы (память, файловые дескрипторы), но сохраняет небольшую запись с кодом завершения (exit status).
  3. Эта запись нужна, чтобы родитель мог узнать, как завершился его потомок (через системный вызов wait() или waitpid()).
  4. Если родитель никогда не вызывает wait(), запись процесса остаётся в системе как "зомби".

Характеристики зомби-процесса:

  • Не потребляет CPU и память (кроме самой записи в таблице процессов).
  • Не может быть "убит" сигналом SIGKILL, так как уже мёртв.
  • Исчезает, когда родительский процесс завершается (все его зомби "усыновляет" init процесс, который периодически вызывает wait()) или когда родитель вызывает wait().

Пример на C:

#include <sys/wait.h>
#include <unistd.h>

int main() {
    pid_t pid = fork();

    if (pid == 0) {
        // Дочерний процесс
        sleep(1);
        _exit(0); // Завершаемся
    } else {
        // Родительский процесс
        sleep(10); // НЕ вызывает wait() → дочерний процесс станет зомби на 9 секунд
        // wait(NULL); // Раскомментировать, чтобы избежать зомби
        sleep(10);
    }
    return 0;
}

Как избежать зомби-процессов в разработке:

  1. Всегда вызывать wait() или waitpid() для завершённых потомков.
  2. Использовать обработчик сигнала SIGCHLD, который уведомляет родителя о завершении потомка.
  3. Дважды вызывать fork() ("fork twice"), чтобы сразу отдавать потомков init.

В iOS/macOS: система управления процессами (launchd, XNU kernel) корректно обрабатывает зомби, поэтому в пользовательских приложениях эта проблема обычно не возникает.