Поиск по сайту:

Что такое «зомби-процесс» в Linux?


Если вы являетесь пользователем Linux, возможно, вы видели процессы-зомби, шаркающие по вашему списку процессов. Вы не можете убить зомби-процесс, потому что он уже мертв — как настоящий зомби.

Зомби — это в основном остатки мертвых процессов, которые не были очищены должным образом. Программа, которая создает процессы-зомби, не запрограммирована должным образом — программы не должны позволять процессам-зомби оставаться на месте.

Что такое зомби-процесс?

Чтобы понять, что такое зомби-процесс и что вызывает появление зомби-процессов, вам нужно немного понять, как процессы работают в Linux.

Когда процесс умирает в Linux, он не сразу полностью удаляется из памяти — его дескриптор процесса остается в памяти (дескриптор процесса занимает лишь небольшой объем памяти). Статус процесса становится EXIT_ZOMBIE, а родитель процесса уведомляется о том, что его дочерний процесс умер с помощью сигнала SIGCHLD. Затем родительский процесс должен выполнить системный вызов wait(), чтобы прочитать статус завершения мертвого процесса и другую информацию. Это позволяет родительскому процессу получать информацию от мертвого процесса. После вызова wait() зомби-процесс полностью удаляется из памяти.

Обычно это происходит очень быстро, поэтому вы не увидите, как зомби-процессы накапливаются в вашей системе. Однако, если родительский процесс запрограммирован неправильно и никогда не вызывает wait(), его потомки-зомби останутся в памяти до тех пор, пока их не очистят.

Такие утилиты, как системный монитор GNOME, команда top и команда ps, отображают зомби-процессы.

Опасности зомби-процессов

Зомби-процессы не потребляют никаких системных ресурсов. (На самом деле каждый из них использует очень небольшой объем системной памяти для хранения своего дескриптора процесса.) Однако каждый процесс-зомби сохраняет свой идентификатор процесса (PID). Системы Linux имеют конечное число идентификаторов процессов — 32767 по умолчанию в 32-разрядных системах. Если зомби накапливаются очень быстро — например, если неправильно запрограммированное серверное программное обеспечение создает процессы-зомби под нагрузкой — весь пул доступных PID в конечном итоге будет назначен процессам-зомби, что предотвратит запуск других процессов.

Тем не менее, несколько зависающих процессов-зомби не являются проблемой, хотя они указывают на ошибку в их родительском процессе в вашей системе.

Избавление от зомби-процессов

Вы не можете убивать процессы-зомби, так как вы можете убивать обычные процессы с помощью сигнала SIGKILL — процессы-зомби уже мертвы. Имейте в виду, что вам не нужно избавляться от зомби-процессов, если только в вашей системе их не много — несколько зомби безвредны. Однако есть несколько способов избавиться от зомби-процессов.

Один из способов — отправить родительскому процессу сигнал SIGCHLD. Этот сигнал говорит родительскому процессу выполнить системный вызов wait() и очистить дочерние процессы-зомби. Отправьте сигнал с помощью команды kill, заменив pid в команде ниже на PID родительского процесса:

kill -s SIGCHLD pid

Однако, если родительский процесс запрограммирован неправильно и игнорирует сигналы SIGCHLD, это не поможет. Вам придется убить или закрыть родительский процесс зомби. Когда процесс, создавший зомби, завершается, init наследует процессы зомби и становится их новым родителем. (init — это первый процесс, запускаемый в Linux при загрузке, и ему назначается PID 1.) init периодически выполняет системный вызов wait() для очистки своих дочерних элементов-зомби, поэтому init быстро справится с зомби. Вы можете перезапустить родительский процесс после его закрытия.

Если родительский процесс продолжает создавать зомби, это должно быть исправлено, чтобы он правильно вызывал функцию wait() для сбора своих дочерних процессов-зомби. Отправьте отчет об ошибке, если программа в вашей системе продолжает создавать зомби.