「サブリーパー」という言葉が一部の回答で使用されています。 Googleを検索すると、その単語が「使用されたばかり」のエントリも表示されます。
「サブリーパー」とは何ですか?
これは、システムコールのフラグとして Linuxカーネル3.4 に実装されました prctl() 。
prctl(2)
マンページから:
[...]サブリーパーは、その子孫プロセスの
init(1)
の役割を果たします。孤立したプロセス(つまり、直接の親がすでに終了している)が終了し、サブリーパーがあるとマークされている場合、最も近くに存在する祖先のサブリーパーはSIGCHLD
シグナルを受け取り、wait(2)
プロセスで終了ステータスを検出します。
プロセスは、prctl(PR_SET_CHILD_SUBREAPER)
を使用して自身をサブリーパーとして定義できます。もしそうなら、孤立した親になる親はinit
(PID 1)ではありません 子プロセス 代わりに、サブリーパーとしてマークされている最も近い生きている祖父母が新しい親になります。生きている祖父母がいない場合、init
はそうします。
このメカニズムを実装する理由は、ユーザースペースサービスマネージャー/スーパーバイザー( upstart
、 systemd
など)が開始されたサービスを追跡する必要があるためです。多くのサービスは、ダブルフォークによってデーモン化し、暗黙的に re-parented をPID 1に取得します。サービスマネージャーは、SIGCHLD
シグナルを受信できなくなり、 wait()
で子を刈り取る責任。子に関するすべての情報は、PID 1が親を変更したプロセスをクリーンアップするときに失われます。これで、サービスマネージャープロセスは、それ自体を一種の「サブ初期化」としてマークすることができ、開始されたサービスによって作成されたすべての孤立したプロセスの親としてとどまることができます。すべてのSIGCHLD
シグナルはサービスマネージャーに配信されます。
Linuxでは、通常、デーモンは forking によって2回作成され、中間プロセスは孫をフォークした後に終了します。これは ゾンビプロセス を回避する一般的な手法です。 initスクリプトは子を呼び出します。その子は再びフォークして、すぐに終了します。孫はinit
によって養子になり、ゾンビを避けるためにwait()
を継続的に呼び出して子供の終了ステータスを収集します。サブリーパーの概念により、ユーザースペースサービスマネージャーがinit
ではなく、新しい親になります。