В UNIX, когда родительский процесс исчезает, я думал, что все дочерние процессы сбрасывают init как своего родителя. Разве это не правильно все время? Есть ли исключения?
В UNIX, когда родительский процесс исчезает, я думал, что все дочерние процессы сбрасывают init как своего родителя. Разве это не правильно все время? Есть ли исключения?
Ответы:
Перемещая мой комментарий к ответу ... Я не верю, что есть исключения.
Обнаружено, что «иногда родительский процесс уничтожается до того, как его дочерний объект уничтожается. В этом случае« родительский процесс всех процессов » init
становится новым PPID (идентификатор родительского процесса). Иногда эти процессы называются« потерянными »процессами». источник
Точно так же описано в блоге IBM : «Родитель умирает или погибает раньше, чем ребенок. В приведенном выше сценарии дочерний процесс становится сиротским процессом (так как он потерял своего родителя). В Linux init
процесс приходит на помощь Сирота обрабатывает и принимает их. Это означает, что после того, как ребенок потерял своего родителя, init
процесс становится его новым родительским процессом ".
Три ответа, написанных в 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. Ожидание возможности прямого вызова демонов из сеансов входа в систему, безусловно, является фундаментальной ошибкой. Но это другой ответ.
procctl()
, Страницы руководства DragonFly BSD. § 2Согласно 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)
.
Я не верю в это. Это всегда идет к процессу инициализации.