Новий батьківський процес, коли батьківський процес гине


22

У UNIX, коли зникає батьківський процес, я вважав, що всі дочірні процеси скидають init як їх батьків. Невже це не завжди правильно? Чи є винятки?

Відповіді:


5

Переміщення мого коментаря до відповіді .... Я не вірю, що є винятки.

Виявлено це "іноді батьківський процес вбивається до того, як його дитина буде вбита. У цьому випадку" батько всіх процесів " initпроцес перетворюється на новий PPID (ідентифікатор батьківського процесу). Колись ці процеси називаються сирітським процесом". джерело

Аналогічно описано в блозі IBM : "Батько помирає або вбивається перед дитиною. У вищеописаному сценарії дочірній процес стає сирітським процесом (оскільки він втратив свого батька). У Linux initпроцес допомагає допомогти сирота обробляє та усиновляє їх. Це означає, що після того, як дитина втратила свого батька, initпроцес стає його новим батьківським процесом ".


61

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

Як зазначає SUS , цитований в одній з інших відповідей тут, тому я більше не буду його цитувати, батьківський процес дітей-сиріт налаштований на процес, визначений реалізацією . Крістіан Ciupitu має рацію ознайомитися з документацією на Linux, щоб побачити, що визначає реалізація. Але його вводить в оману ця документація, яка є непослідовною і не є актуальною.

За два роки до написання цих трьох відповідей, і швидко з'явившись до трьох років тому під час першого написання цієї відповіді, ядро ​​Linux змінилося. Розробники системних систем додали можливість процесам налаштовувати себе як "підреактори". З Linux 3.4 процеси можуть надати prctl()системний виклик з PR_SET_CHILD_SUBREAPERможливістю вибору, і в результаті вони, не обробляючи номер 1, стануть батьком будь-якого зі своїх осиротілих нащадків. Сторінка " man" для сторінки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 для отримання додаткової інформації про початковий сеанс init, зокрема.
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.