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

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

В Linux процесс-зомби — это процесс, который завершил свое выполнение и был прерван с помощью системного вызова exit(), но все еще имеет свою запись в таблице процессов системы. Процесс-зомби также известен как недействующий процесс, потому что он представлен в таблице процессов только под этим именем. На самом деле, процесс Zombie не является ни живым, ни мертвым, как оригинальный зомби.

Как создается зомби-процесс?

В среде Linux мы создаем дочерний процесс с помощью системного вызова fork(). И процесс, который вызывает системный вызов fork(), называется родительским процессом.

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

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

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

**Сигнал SIGCHLD: когда с дочерним процессом происходит что-то интересное, например, он останавливается или завершается, сигнал SIGCHLD отправляется родительскому процессу дочернего процесса, чтобы он мог прочитать статус выхода дочернего процесса. По умолчанию ответом на этот сигнал SIGCHLD является его игнорирование.

Процесс зомби и процесс сирота

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

Процесс-сирота может быть двух типов:

  1. Намеренно потерянный процесс. Намеренно потерянный процесс — это процесс-сирота, который генерируется, когда нам нужно либо запустить/запустить бесконечно работающую службу, либо завершить длительную задачу, не требующую вмешательства пользователя. Эти процессы выполняются в фоновом режиме и обычно не требуют ручной поддержки.
  2. Непреднамеренно осиротевший процесс: непреднамеренно осиротевший процесс — это процесс-сирота, который генерируется, когда какой-либо родительский процесс дает сбой или завершается, оставляя дочерний процесс в активном или работающем состоянии. В отличие от процесса Intentionally Orphaned, пользователь может управлять этими процессами или избегать их, используя механизм группы процессов.

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

Ниже приведены некоторые характеристики процесса зомби:

Статус выхода процесса-зомби может быть прочитан родительским процессом, перехватившим сигнал SIGCHLD с помощью системного вызова wait().

Когда родительский процесс считывает статус выхода процесса-зомби, его запись извлекается из таблицы процессов.

После извлечения процесса-зомби из таблицы процессов его PID (идентификатор процесса) и запись в таблице процессов могут быть повторно использованы каким-либо новым процессом в системе.

Если родительский процесс процесса-зомби прерывается или завершается, то наличие записи процесса-зомби в таблице процессов приводит к ошибке операционной системы.

Обычно процесс-зомби можно уничтожить, отправив родительскому процессу сигнал SIGCHLD с помощью команды kill.

Если процесс-зомби не может быть уничтожен даже путем отправки сигнала SIGCHLD его родительскому процессу, мы можем завершить его родительский процесс, чтобы убить процесс-зомби.

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

Угрозы, связанные с зомби-процессами

Хотя процесс-зомби не использует никаких системных ресурсов, но сохраняет свою запись (PID) в таблице процессов системы. Но вызывает беспокойство ограниченный размер таблицы процессов системы. Каждый активный процесс имеет действительную запись в таблице процессов системы.

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

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

Более того, присутствие процесса-зомби вызывает ошибку операционной системы, когда его родительские процессы не активны.

Это не вызывает беспокойства, если в системе всего несколько процессов-зомби, но может стать серьезной проблемой для системы, когда в системе так много процессов-зомби.

Как убить процесс зомби?

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

Посмотреть такие процессы можно с помощью утилиты ps, здесь они отмечаются как defunct:

ubuntu:~$ps aux | grep defunct
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
user1      108  0.0  0.0      0     0 tty1     Z    16:25   0:00 [zombie] <defunct> 

Если вы попытаетесь убить такой процесс с помощью сигнала KILL, то ничего не выйдет.

Следовательно мы должны уничтожить этот процесс Zombie, отправив сигнал SIGCHLD родительскому процессу с помощью команды kill в Linux.

Сначала нужно найти родительский процесс:

$ ps -A -ostat,pid,ppid | grep -e '[zZ]'
Z      108   103

Когда родительский процесс получает сигнал SIGCHLD, он уничтожает процесс-зомби, извлекая его запись из таблицы процессов с помощью системного вызова wait(). Ниже приведена демонстрация команды Linux для ручного уничтожения процесса Zombie:

ubuntu:~$ kill -s SIGCHLD 103

Если каким-либо образом процесс-зомби не может быть уничтожен даже путем отправки сигнала SIGCHLD родительскому процессу, мы можем завершить его родительский процесс, после чего процесс-зомби будет принят процессом инициализации (PID = 1).

Этот процесс инициализации теперь становится новым родителем процесса Zombie, который регулярно выполняет системный вызов wait() для перехвата сигнала SIGCHLD для чтения состояния выхода процесса Zombie и получения его из таблицы процессов. Ниже приведена команда Linux для уничтожения родительского процесса:

ubuntu:~$ kill -9 103

ПРИМЕЧАНИЕ. В обеих приведенных выше командах Linux просто замените на PID (идентификатор процесса) родительского процесса зомби.

📑 Похожие статьи на сайте
При перепечатке просьба вставлять активные ссылки на oslogic.ru
Copyright oslogic.ru © 2022 . All Rights Reserved.