web-dev-qa-db-ja.com

親プロセスが停止したときの新しい親プロセス

UNIXでは、親プロセスが消えると、すべての子プロセスが親としてinitをリセットすると思いました。これは常に正しくありませんか?例外はありますか?

23
user100503

コメントを回答に移動しています...例外はないと思います。

この「子プロセスが強制終了される前に親プロセスが強制終了される場合があります。この場合、「すべてのプロセスの親」であるinitプロセスが新しいPPID(親プロセスID)になります。これらのプロセスが呼び出される場合があります孤立プロセス。」 ソース

IBMの blog でも同様に説明されています。「親が子より先に死亡するか殺されます。上記のシナリオでは、子プロセスは(親を失ったため)孤立プロセスになります。Linuxでは、 initプロセスは、Orphanプロセスを救い、それらを採用します。これは、子が親を失った後、initプロセスが新しい親プロセスになることを意味します。」

5
Simply_Me

2014年に書かれた3つの回答はすべて、UnicesとLinuxではプロセスは例外なくプロセス#1に親変更されることを示しています。 3つの間違った答え。 ☺

[〜#〜] sus [〜#〜] が言うように、ここでは他の回答のいずれかで引用されているので、再度引用しないように、孤立した子の親プロセスはimplementation-definedプロセス。 Cristian Ciupituは、Linuxのドキュメントを調べて、実装の定義を確認するのが適切です。しかし、彼は一貫性がなく最新ではないそのドキュメントに惑わされています。

これらの3つの回答が書かれる2年前、そしてこの回答が最初に書かれたときから3年前までに、Linuxカーネルは変わりました。 systemd開発者は、プロセスが自分自身を「サブリーパー」として設定する機能を追加しました。 Linux 3.4以降、プロセスは_PR_SET_CHILD_SUBREAPER_オプションを使用してprctl()システムコールを発行でき、その結果、プロセス#1ではなく、プロセスは孤立した子孫プロセスの親になります。 prctl() のマニュアルページは最新ですが、他のマニュアルページは最新ではなく、一貫性があります。

バージョン10.2では、FreeBSDは同じ機能を獲得し、_PROC_REAP_ACQUIRE_および_PROC_REAP_RELEASE_オプションを使用して既存のprocctl()システムコールを拡張しました。 DragonFly BSDからこのメカニズムを採用しました。これはバージョン4.2で取得され、元々はreapctl()という名前でしたが、開発中にprocctl()に名前が変更されました。

したがって、例外があり、かなり目立つものがあります。Linux、FreeBSD/PC-BSD、およびDragonFly BSDでは、孤立した子の親プロセスは、サブリーパーまたはプロセス#1としてマークされている子の最も近い祖先プロセスに設定されます。祖先サブリーパープロセスがない場合。 systemd(開発者が最初にこれをLinuxカーネルに組み込んだもの)、upstart、nosh _service-manager_など、さまざまなデーモン監視ユーティリティがすでにこれを利用しています。

そのようなデーモン監視プログラムがプロセス#1ではなく、対話型ログインセッションなどのサービスを生成し、そのセッションで (かなり間違った)トリックをダブルfork() ing の場合、プロセスは、プロセス#1ではなく、デーモンスーパーバイザの子になります。もちろん、ログインセッション内から直接デーモンを生成できると期待することは、根本的な誤りです。しかし、それは別の答えです。

参考文献

62
JdeBP

The SingleUNIX®Specification、Version 2の exit manページによると、

呼び出しプロセスのすべての既存の子プロセスとゾンビプロセスの親プロセスIDは、実装に依存するシステムプロセスのプロセスIDに設定されます。つまり、これらのプロセスは特別なシステムプロセスによって継承されます。

ほとんどのUnixバリアントでは、その特別なプロセスはinit(PID 1)です。

Linux wait(2) manページはこれを確認しています:

親プロセスが終了すると、その「ゾンビ」子(存在する場合)がinit(8)によって採用され、ゾンビの削除を自動的に待機します。

FreeBSD wait(2) 、NetBSD wait(2) 、OpenBSD wait(2) およびMac OS X wait(2) manページでもこれを確認しています:

親プロセスが、すべての子プロセスの終了を待たずに終了した場合、残りの子プロセスには、親プロセス1 ID(initプロセスID)が割り当てられます。

Oracle Solaris 11.1 wait(3C) のマニュアルページでも確認しています。

親プロセスが子プロセスの終了を待たずに終了した場合、各子プロセスの親プロセスIDは1に設定され、初期化プロセスは子プロセスを継承します。 Intro(2) を参照してください。

9

私はそうは思いません。それは常にinitプロセスに行きます。

http://en.wikipedia.org/wiki/Orphan_process

3
Rich Remer