For faster navigation, this Iframe is preloading the Wikiwand page for Процесс-зомби.

Процесс-зомби

Материал из Википедии — свободной энциклопедии

Проце́сс-зо́мби, зо́мби (англ. zombie process, англ. defunct process) — дочерний процесс в Unix-системе, завершивший своё выполнение, но ещё присутствующий в списке процессов операционной системы, чтобы дать родительскому процессу считать код завершения.

Этимология

[править | править код]

Происходит от слова «зомби», означающего «живой мертвец» (оксюморон, англ. undead). Термин является яркой метафорой о том, что процесс «умер», но не «погребён».

Возникновение зомби

[править | править код]

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

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

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

Проблемы зомби

[править | править код]

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

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

Иногда, если родительский процесс выполняется от имени суперпользователя, для освобождения записей (перезапуска процесса) может потребоваться перезагрузка (причём зачастую — только аппаратным рестартом). Некоторые операционные системы (например, Sun Solaris) при возникновении такой ситуации аварийно завершают часть выполняющихся процессов, восстанавливая работоспособность системы.

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

Игнорирование обработки завершения дочерних процессов не является правильным, но обычно не приводит к проблемам для короткоживущих программ, так как при завершении процесса все его потомки становятся потомками процесса init, который постоянно считывает статус своих потомков-зомби, очищая таблицу процессов. Именно для задействования этого механизма выполняется стандартная техника запуска демонов «double fork()»: промежуточный родитель завершается, делая родителем своего потомка процесс init .

Для долгоживущих и часто создающих дочерние процессы программ необходима корректная обработка контроля завершения дочерних программ, потому что накапливание необрабатываемых зомби приводит к «утечке ресурсов» в виде накопления записей в таблице процессов.

В linux, начиная с версии kernel 3.4, процесс имеет возможность объявить себя усыновителем сирот («subreaper») вместо процесса init командой prctl(PR_SET_CHILD_SUBREAPER).

Примеры программ, создающих зомби, на разных языках программирования

[править | править код]
Выполнение данных примеров может привести к потере несохранённых данных. Не рекомендуется выполнять их без применения надлежащих мер предосторожности.
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main ()
{
  pid_t child_pid;

  child_pid = fork ();
  if (child_pid > 0) {
    sleep (60);
  }
  else {
    exit (0);
  }
  return 0;
}
#!/usr/bin/env python2
# -*- coding: utf8 -*-

import subprocess
import time
import threading

# Порождаем процесс 'ls' с параметром '-l'
proc = subprocess.Popen(['ls','-l'])

# Останавливаем главный поток программы на 5 секунд. На их протяжении процесс будет иметь
# статус "зомби", хоть процесс уже и завершился, поскольку не была выполнена обработка
# результата процесса
time.sleep(5)

# В этом месте зомби исчезнет, т.к. программа очистит буферы ввода-вывода для процесса
# и считает код его завершения
proc.communicate()

time.sleep(5)
  • Зомби не могут принимать сигналы, и поэтому их нельзя убрать с помощью утилиты или вызова kill. Убрать их может либо родительский процесс, либо его завершение.
  • Все процессы в Unix имеют своих родителей — процессы, не имеющие или потерявшие родителей («осиротевшие» процессы; англ. orphan process), являются дочерними для init (процесс с PID = 1), который, в свою очередь, является дочерним для ядра (процесса с PID = 0). init всегда обрабатывает SIGCHLD, поэтому от таких процессов никогда не остаётся зомби.
  • Зомби можно узнать в списке процессов (выводимых утилитой ps) по флагу «Z» в колонке STAT.
  • Хорошим стилем программирования считается всегда обрабатывать SIGCHLD.
  • Языки скриптов Perl и Python неявно обрабатывают SIGCHLD, если программа настраивает его игнорирование.
В статье не хватает ссылок на источники (см. рекомендации по поиску). Информация должна быть проверяема, иначе она может быть удалена. Вы можете отредактировать статью, добавив ссылки на авторитетные источники в виде сносок. (8 июня 2019)
{{bottomLinkPreText}} {{bottomLinkText}}
Процесс-зомби
Listen to this article

This browser is not supported by Wikiwand :(
Wikiwand requires a browser with modern capabilities in order to provide you with the best reading experience.
Please download and use one of the following browsers:

This article was just edited, click to reload
This article has been deleted on Wikipedia (Why?)

Back to homepage

Please click Add in the dialog above
Please click Allow in the top-left corner,
then click Install Now in the dialog
Please click Open in the download dialog,
then click Install
Please click the "Downloads" icon in the Safari toolbar, open the first download in the list,
then click Install
{{::$root.activation.text}}

Install Wikiwand

Install on Chrome Install on Firefox
Don't forget to rate us

Tell your friends about Wikiwand!

Gmail Facebook Twitter Link

Enjoying Wikiwand?

Tell your friends and spread the love:
Share on Gmail Share on Facebook Share on Twitter Share on Buffer

Our magic isn't perfect

You can help our automatic cover photo selection by reporting an unsuitable photo.

This photo is visually disturbing This photo is not a good choice

Thank you for helping!


Your input will affect cover photo selection, along with input from other users.

X

Get ready for Wikiwand 2.0 🎉! the new version arrives on September 1st! Don't want to wait?