WikiDer > Зомби-процесс
Эта статья нужны дополнительные цитаты для проверка. (Сентябрь 2014 г.) (Узнайте, как и когда удалить этот шаблон сообщения) |
На Unix и Unix-подобный компьютер операционные системы, а зомби процесс или же несуществующий процесс это процесс который завершил выполнение (через выход
системный вызов), но все еще есть запись в таблица процессов: это процесс в "Прекращенное состояние". Это происходит для дочерние процессы, где запись по-прежнему необходима, чтобы разрешить родительский процесс читать детскую статус выхода: как только статус выхода считывается через ждать
системный вызов, запись зомби удаляется из таблицы процессов и называется "пожинаемой". Дочерний процесс всегда сначала становится зомби, а затем удаляется из таблицы ресурсов. В большинстве случаев при нормальной работе системы зомби немедленно ждут своих родителей, а затем пожинает система - процессы, которые остаются зомби в течение длительного времени, обычно являются ошибкой и вызывают утечка ресурсов, но единственный ресурс, который они занимают, - это запись в таблице процессов - идентификатор процесса.
Период, термин зомби процесс происходит из общего определения зомби - ан нежить человек. В метафоре этого термина дочерний процесс «умер», но еще не умер »пожала". Кроме того, в отличие от обычных процессов, убийство
команда не влияет на зомби-процесс.
Зомби-процессы не следует путать с сиротские процессы: сиротский процесс - это процесс, который все еще выполняется, но родитель которого умер. Когда родитель умирает, осиротевший дочерний процесс принимается в этом
(идентификатор процесса 1). Когда процессы-сироты умирают, они не остаются как процессы-зомби; вместо этого они ждать
ed on by в этом
. В результате процесс, который одновременно является зомби и сиротой, будет завершен автоматически.
Обзор
Когда процесс заканчивается через выход
, вся память и связанные с ней ресурсы освобождаются, чтобы их могли использовать другие процессы. Однако запись процесса в таблице процессов остается. Родитель может прочитать статус выхода ребенка, выполнив ждать
системный вызов, после чего зомби удаляется. В ждать
вызов может выполняться в последовательном коде, но обычно он выполняется в обработчик для SIGCHLD сигнал, который родитель получает, когда умирает ребенок.
После удаления зомби его идентификатор процесса (PID) и запись в таблице процессов могут быть повторно использованы. Однако, если родитель не может позвонить ждать
, зомби останется в таблице процессов, что вызовет утечка ресурсов. В некоторых ситуациях это может быть желательно - родительский процесс желает продолжать удерживать этот ресурс - например, если родительский процесс создает другой дочерний процесс, он гарантирует, что ему не будет назначен тот же PID. В современных UNIX-подобных системах (которые соответствуют SUSv3 спецификации в этом отношении) применяется следующий особый случай: если родительский явно игнорирует SIGCHLD, устанавливая его обработчик на SIG_IGN
(вместо того, чтобы просто игнорировать сигнал по умолчанию) или имеет SA_NOCLDWAIT
установлен флаг, вся информация о статусе дочернего выхода будет отброшена, и никаких зомби-процессов не останется.[1]
Зомби можно идентифицировать в выводе Unix пс
команда по наличию "Z
"в столбце" СТАТИСТИКА ".[2] Зомби, которые существуют более короткого периода времени, обычно указывают на ошибку в родительской программе или просто на необычное решение не пожинать детей (см. Пример). Если родительская программа больше не работает, зомби-процессы обычно указывают на ошибку в операционной системе. Как и в случае с другими утечками ресурсов, присутствие нескольких зомби само по себе не вызывает беспокойства, но может указывать на проблему, которая может стать серьезной при более высоких нагрузках. Поскольку для зомби-процессов не выделяется память - единственная системная память используется для самой записи в таблице процессов - основная проблема многих зомби заключается не в нехватке памяти, а в исчерпании записей в таблице процессов, в частности, идентификаторов процессов.
Чтобы удалить зомби из системы, SIGCHLD сигнал можно отправить родителю вручную, используя убийство
команда. Если родительский процесс по-прежнему отказывается пожать зомби, и если можно было бы завершить родительский процесс, следующим шагом может быть удаление родительского процесса. Когда процесс теряет своего родителя, в этом
становится его новым родителем. в этом
периодически выполняет ждать
системный вызов, чтобы пожать любых зомби с в этом
как родитель.
Пример
Синхронно ожидание определенных дочерних процессов в (определенном) порядке может привести к тому, что зомби будут присутствовать дольше, чем упомянутый выше «короткий период времени». Это не обязательно ошибка программы.
#включают <sys/wait.h>#включают <stdlib.h>#включают <unistd.h>int главный(пустота){ pid_t pids[10]; int я;за (я = 9; я >= 0; --я) { pids[я] = вилка(); если (pids[я] == 0) { printf("Ребенок% d",я); спать(я+1); _выход(0); }}за (я = 9; я >= 0; --я){ printf("родитель% d",я); waitpid(pids[я], НОЛЬ, 0); }возвращаться 0;}
Выход
parent9Child3Child4Child2Child5Child1Child6Child0Child7Child8Child9 // здесь есть паузаparent8parent7parent6parent5parent4parent3parent2parent1parent0
Объяснение
В первом цикле исходный (родительский) процесс разветвляет 10 своих копий. Каждый из этих дочерних процессов (обнаруженных по тому факту, что fork () вернул ноль) печатает сообщение, засыпает и завершает работу. Все дочерние элементы создаются по существу в одно и то же время (поскольку родительский элемент очень мало делает в цикле), поэтому случайность, когда каждый из них запускается в первый раз, - таким образом, порядок их сообщений зашифрован.
Во время цикла создается массив идентификаторов дочерних процессов. Копия массива pids [] есть во всех 11 процессах, но только в родительском она является полной - в копии в каждом дочернем процессе будут отсутствовать дочерние PID с меньшими номерами, а собственный PID будет иметь ноль. (Не то чтобы это действительно важно, поскольку этот массив фактически использует только родительский процесс.)
Второй цикл выполняется только в родительском процессе (потому что все дочерние элементы завершились до этого момента) и ожидает завершения каждого дочернего процесса. Он ждет ребенка, который спал 10 секунд первым; все остальные уже давно закрыты, поэтому все сообщения (кроме первого) появляются в быстрой последовательности. Здесь нет возможности случайного упорядочения, поскольку он управляется циклом в одном процессе. Обратите внимание, что первое родительское сообщение фактически появилось перед любым из дочерних сообщений - родительский процесс смог продолжить работу во втором цикле до того, как любой из дочерних процессов смог запуститься. Это опять же случайное поведение планировщика процессов - сообщение «parent9» могло появиться где угодно в последовательности до «parent8».
От Child0 до Child8 в этом состоянии проводят одну или несколько секунд между моментом выхода и временем, когда родитель выполняет для них waitpid (). Родитель уже ждал Child9, прежде чем он завершился, так что один процесс практически не проводил времени как зомби. [3]
Смотрите также
Рекомендации
- ^ "wait (2) Man Page". Руководство программиста Linux.
- ^ «Зомби (5) - UNIX System V (Концепции)». Детектор коллайдера в Фермилабе.
- ^ https://stackoverflow.com/questions/42627411/can-someone-please-explain-how-this-worksfork-sleep
- "Страницы руководства UNIX: ps ()". UNIXhelp для пользователей. Архивировано из оригинал на 2013-03-08.