知識ベース

親プロセス

コンピューティングでは、 親プロセスは、1つ以上の子プロセスを作成したプロセスです。

Unixライクシステム

Unixライクなオペレーティングシステムでは、別のプロセスがfork()システムコールを実行すると、プロセス0(スワッパー)を除くすべてのプロセスが作成されます。 forkを呼び出したプロセスは親プロセスであり、新しく作成されたプロセスは子プロセスです。すべてのプロセス(プロセス0を除く)には1つの親プロセスがありますが、多くの子プロセスを持つことができます。

オペレーティングシステムカーネルは、プロセス識別子によって各プロセスを識別します。プロセス0は、システムの起動時に作成される特別なプロセスです。子プロセス(プロセス1)をフォークした後、プロセス0はスワッパープロセス(「アイドルタスク」とも呼ばれる)になります。 initとして知られるプロセス1は、システム内の他のすべてのプロセスの祖先です。

Linux

プロセスとPOSIXスレッドの間に非常にわずかな違いがあるLinuxカーネルには、2種類の親プロセス、つまり実際の親と親があります。親は、子の終了時にSIGCHLDシグナルを受信するプロセスです。一方、実際の親は、マルチスレッド環境でこの子プロセスを実際に作成したスレッドです。通常のプロセスでは、これら2つの値は両方とも同じですが、プロセスとして動作するPOSIXスレッドでは、これら2つの値は異なる場合があります。

ゾンビプロセス

オペレーティングシステムは、そのプロセス識別子(一般に " pid "と呼ばれる)を使用して、その機能に必要なデータにすべてのプロセスを関連付けるテーブルを維持します。プロセスの存続期間中、そのようなデータには、プロセスに指定されたメモリセグメント、それが呼び出された引数、環境変数、リソース使用量に関するカウンター、ユーザーID、グループID、およびグループセット、およびその他の情報が含まれる場合があります。

exitを呼び出して(暗黙的であっても、 main関数からreturnコマンドを実行して)、またはプロセスを突然終了させる信号を受信して​​、プロセスの実行を終了すると、オペレーティングシステムは、関連するリソースと情報のほとんどを解放します。そのプロセスは、リソース使用率と終了ステータスコードに関するデータを保持します。これは、親プロセスがその子が正常に実行されたかどうか(終了ステータスコードをデコードする標準関数を使用して)およびシステムリソースの量を知りたいためです。実行中に消費されます。

デフォルトでは、システムは、子プロセスの終了時に親プロセスが実際にそのような情報に関心があると想定するため、親にシグナルSIGCHLDを送信して、子に関するデータが収集されることを警告します。このような収集は、 待機ファミリの関数( 待機自体、またはwaitpidwaitidまたはwait4などのその親族のいずれか)を呼び出すことによって行われます 。このコレクションが作成されるとすぐに、システムは子プロセスに関する最後の情報を解放し、プロセステーブルからそのpidを削除します。ただし、親プロセスが子のデータの収集に遅れる(またはまったく行わない)場合、システムにはオプションがなく、子のpidおよび終了データをプロセステーブルに無期限に保持します。

そのデータが収集されていなかったような終了したプロセスは、UNIXの用語で、単にゾンビプロセス 、またはゾンビと呼ばれています。この名前は、終了したプロセスを「もはや生きていない」または「死んでいる」と見なしているためにユーモラスなアナロジーです。実際に機能しなくなっているためです。テーブル-したがって、実際には「アンデッド」または「ゾンビ」です。

ゾンビプロセスは、リソースが限られているシステムやプロセステーブルのサイズが制限されているシステムで問題を引き起こす可能性があります。新しいアクティブプロセスの作成は、長持ちするゾンビが使用するリソースの不足によって妨げられる可能性があるためです。

そのため、子プロセスを生成して、元の子からの長続きするゾンビの形成を防ぐためのコードを作成する可能性のあるプログラムでは、プログラミングを実践することをお勧めします。最も明白なアプローチは、新しいプロセスを作成した後、どこかでwaitまたはその親類を呼び出すコードを使用することです。非同期に実行され、予測できない順序で終了する可能性のある多くの子プロセスをプログラムが作成することが予想される場合、未収集の子がなくなるまで、ループでwait -family関数の1つを呼び出すSIGCHLDシグナルのハンドラーを作成することをお勧めしますデータが残ります。親プロセスは、その子プロセスの終了を完全に無視し、ゾンビを作成することはできませんが、特別なオプションフラグSA_NOCLDWAITを使用してsigactionを呼び出すことにより、 SIGCHLDのハンドラーの明示的な定義が必要です

孤立プロセス

孤立プロセスは、ゾンビプロセスとは反対の状況です。親プロセスが子プロセスの前に終了し、「孤立」と呼ばれる場合を指します。子プロセスが終了するときに(SIGCHLDシグナルを介して)発生する非同期の子から親への通知とは異なり、子プロセスは親が終了してもすぐには通知されません。代わりに、システムは、子プロセスのデータの「親PID」フィールドを、システム内の他のすべてのプロセスの「祖先」であるプロセスに再定義します。PIDの値は通常1(1)で、従来は「init」です。したがって、initはシステム上のすべての孤立プロセスを「採用」すると言われていました。

UNIXを初めて使用するプログラマーのやや一般的な前提は、終了プロセスの子プロセスがこのプロセスの直接の親プロセスに採用されるということです(したがって、それらの子プロセスの「祖父母」)。もちろん、「祖父母」が初期化そのものでない限り、そのような仮定は正しくありませんでした。

Linuxカーネル3.4以降、これは真実ではなくなりました。実際、プロセスはPR_SET_CHILD_SUBREAPERオプションを指定してprctl()システムコールを発行できます。その結果、プロセス#1ではなく、プロセスが親のない子孫プロセスの親になります。これは、systemd、upstart、noshサービスマネージャーを含む最新のサービスマネージャーとデーモン監視ユーティリティの動作方法です。

これはマニュアルページの要約であり、次のことを報告しています:

サブリーパーは、その子孫プロセスのinit(1)の役割を果たします。プロセスが孤立する(つまり、その直接の親が終了する)と、そのプロセスは最も近いまだ生きている祖先のサブリーパーに親が変更されます。その後、孤立したプロセスでgetppid()を呼び出すと、サブリーパープロセスのPIDが返されます。孤立したプロセスが終了すると、サブリーパープロセスがSIGCHLDシグナルを受信し、プロセスでwait(2)できるようになります。終了ステータスを検出します。