Новый родительский процесс, когда родительский процесс умирает


22

В UNIX, когда родительский процесс исчезает, я думал, что все дочерние процессы сбрасывают init как своего родителя. Разве это не правильно все время? Есть ли исключения?

Ответы:


5

Перемещая мой комментарий к ответу ... Я не верю, что есть исключения.

Обнаружено, что «иногда родительский процесс уничтожается до того, как его дочерний объект уничтожается. В этом случае« родительский процесс всех процессов » initстановится новым PPID (идентификатор родительского процесса). Иногда эти процессы называются« потерянными »процессами». источник

Точно так же описано в блоге IBM : «Родитель умирает или погибает раньше, чем ребенок. В приведенном выше сценарии дочерний процесс становится сиротским процессом (так как он потерял своего родителя). В Linux initпроцесс приходит на помощь Сирота обрабатывает и принимает их. Это означает, что после того, как ребенок потерял своего родителя, initпроцесс становится его новым родительским процессом ".


61

Три ответа, написанных в 2014 году, все говорят о том, что в Unices и в Linux процесс перераспределяется в процесс № 1 без исключения. Три неправильных ответа. ☺

Как говорит SUS , цитируемый в одном из других ответов здесь, поэтому я не буду его цитировать снова, родительский процесс детей-сирот настроен на процесс, определяемый реализацией . Кристиан Чиупиту (Cristian Ciupitu) вправе обратиться к документации Linux, чтобы увидеть, что определяет реализация. Но его вводит в заблуждение эта документация, которая является непоследовательной и не актуальной.

За два года до того, как были написаны эти три ответа, и вскоре после того, как был написан первый ответ, три года назад ядро ​​Linux изменилось. Разработчики systemd добавили возможность для процессов устанавливать себя как «подзадачи». Начиная с Linux 3.4, процессы могут выполнять prctl()системный вызов с PR_SET_CHILD_SUBREAPERопцией, и в результате они, а не процесс № 1, станут родителями любого из своих потерянных дочерних процессов. Страница людей дляprctl() это уточненного, но другие страниц человека не были доведены до даты и в соответствии.

В версии 10.2 FreeBSD получила такую ​​же возможность, расширив свой существующий procctl()системный вызов с помощью PROC_REAP_ACQUIREи PROC_REAP_RELEASEопций. Он принял этот механизм от DragonFly BSD; который получил его в версии 4.2, первоначально названной, reapctl()но переименованной во время разработки в procctl().

Таким образом, есть исключения, и довольно заметные: в Linux, FreeBSD / PC-BSD и DragonFly BSD родительский процесс детей-сирот установлен на процесс ближайшего предка дочернего процесса, который помечен как подпочерник, или процесс # 1 если нет предшественника подпочвенного процесса. Различные утилиты для наблюдения за демонами, в том числе systemd (разработчики которого изначально поместили это в ядро ​​Linux), upstart и nosh service-manager- уже используют это.

Если такой руководитель демона не обрабатывает # 1, и это порождает услугу , например, интерактивный сеанс входа в системе , а также в том , что один сеанс делает на (весьма неправильно) трюк в попытке «демон», дважды fork()Ингами , то СВОЙ процесс будет в конечном итоге он является дочерним элементом администратора демона, а не процесса № 1. Ожидание возможности прямого вызова демонов из сеансов входа в систему, безусловно, является фундаментальной ошибкой. Но это другой ответ.

дальнейшее чтение


Я на самом деле заметил потерянные процессы, привязанные к сеансу init (в Ubuntu с Upstart), но никогда не осознавал его значения. +1
Муру

См. Unix.stackexchange.com/a/194208/5132 для получения дополнительной информации об инициации сеанса upstart, в частности.
JdeBP

8

Согласно exitсправочной странице из Единой спецификации UNIX®, версия 2:

Идентификатор родительского процесса всех существующих дочерних процессов и процессов-зомби вызывающего процесса устанавливается равным идентификатору процесса зависящего от реализации системного процесса. То есть эти процессы наследуются специальным системным процессом.

Для большинства вариантов Unix этот специальный процесс init(PID 1).

Справочная wait(2)страница Linux подтверждает это:

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

Справочные страницы FreeBSD wait(2), NetBSD wait(2), OpenBSD wait(2)и Mac OS X также wait(2)подтверждают это:

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

Справочная wait(3C)страница Oracle Solaris 11.1 также подтверждает это:

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


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.