UNIXでは、親プロセスが消えると、すべての子プロセスが親としてinitをリセットすると考えました。これは常に正しくないですか?例外はありますか?
UNIXでは、親プロセスが消えると、すべての子プロセスが親としてinitをリセットすると考えました。これは常に正しくないですか?例外はありますか?
回答:
2014年に書かれた3つの回答では、すべてがUnicesおよびLinuxで、プロセスは例外なくプロセス#1に親に変更されたと述べています。3つの間違った答え。☺
SUSは言い、ここで他の回答の一つに引用されたので、私は再びそれを引用しませんが、孤児の親プロセスがに設定されている実装定義のプロセス。Cristian Ciupituは、Linuxのドキュメントを参照して、実装の定義を確認する権利があります。しかし、彼は一貫性がなく、最新ではないそのドキュメントに惑わされています。
これらの3つの答えが書かれる2年前、そしてこの答えを最初に書いた3年前に急いで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
The SingleUNIX®Specification、バージョン2 の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)
マニュアルページでもこれが確認されています。
すべての子プロセスが終了するのを待たずに親プロセスが終了した場合、残りの子プロセスには親プロセス1 ID(initプロセスID)が割り当てられます。
Oracle Solaris 11.1のwait(3C)
マニュアルページでもこれが確認されています。
子プロセスの終了を待たずに親プロセスが終了した場合、各子プロセスの親プロセスIDは1に設定され、初期化プロセスは子プロセスを継承します。をご覧ください
Intro(2)
。
私はそうは思わない。常に初期化プロセスに進みます。