終了プロセス
プロセスが作成された後、どのように終了するのでしょうか?プロセスの終了は、システムリソースが効果的に管理されることを保証する、プロセスライフサイクルの重要な部分です。
プロセスは通常、_exitシステムコールを呼び出すことによって終了します。このアクションは、プロセスが完了し、メモリやファイル記述子などのリソースを再取得できることをカーネルに通知します。終了する際、プロセスはカーネルに終了ステータス(整数値)を提供します。慣例として、ステータス 0 は正常な実行を示し、ゼロ以外の値はエラーを示します。
しかし、_exitを呼び出してもプロセスは直ちに消滅しません。親プロセスは、waitシステムコールを使用して、子プロセスの終了を認識する必要があります。このコールにより、親は子の終了ステータスを取得できます。この 2 段階のメカニズムは、適切なプロセスクリーンアップに不可欠です。linux kill child processを行う別の方法はシグナルを使用することですが、これは後のレッスンで詳しく説明します。
孤児プロセス
親プロセスが子プロセスより先に終了した場合はどうなるでしょうか?子プロセスは「孤児(orphan)」になります。元の親がwaitを呼び出せなくなるため、カーネルが介入します。孤児プロセスは直ちに特別なシステムプロセス、通常はすべてのプロセスの祖先と見なされるinit(プロセス ID 1)に引き取られます。その後、initプロセスが親の役割を引き継ぎ、採用したすべての子プロセスの終了ステータスを定期的にwaitで収集し、それらがきれいに終了できるようにします。
ゾンビプロセス
子プロセスが終了したが、親プロセスがまだwaitを呼び出していない場合、異なるシナリオが発生します。この状態では、子プロセスは「ゾンビ(zombie)」プロセスになります。カーネルはゾンビのほとんどのリソースを解放しますが、プロセステーブルのエントリは保持します。このエントリにはプロセス ID と終了ステータスが含まれ、親がそれを収集するのを待ちます。
ゾンビプロセスはすでに死んでいるため、CPU 時間を消費しません。実行されていないため、シグナルでキルすることはできません。親プロセスがwaitを呼び出してゾンビをクリーンアップするプロセスを「レーク(reaping)」と呼びます。親プロセスがwaitを呼び出さない場合、これらのゾンビは蓄積する可能性があります。少数であれば無害ですが、多数になるとプロセステーブルが満杯になり、新しいプロセスの作成を防ぐ可能性があります。親プロセスも終了した場合、initがゾンビを引き取り、レークします。
ゾンビプロセス vs 孤児プロセス
zombie vs orphan processの違いを理解することは、プロセス関連の問題を診断するための鍵となります。
- 孤児プロセスは、親が死んだアクティブな実行中のプロセスです。
initに引き取られ、終了するまで実行を続けます。 - ゾンビプロセスは、実行を完了したが、まだプロセステーブルにエントリが残っている、死んだプロセスです。親プロセスが終了ステータスを読み取るのを待っています。
要するに、孤児は生きているが親がいないのに対し、ゾンビは死んでいるがまだ親によって完全にレークされていない状態です。