1. ゾンビプロセスとは
ゾンビプロセスとは、親プロセスが終了した(親プロセスがそれを待機しなかった(wait/waitpidを呼び出す))ことを意味し、終了後にプロセスを受け入れるプロセスがなかった場合、ゾンビプロセス、つまり (ゾンビ) プロセス。
2. ゾンビプロセスはどのように生成されるのでしょうか?
プロセスがその寿命を終了するために exit コマンドを呼び出すと、実際には破壊されず、ゾンビプロセス (Zombie) と呼ばれるプロセスが残されます。システムコール exit の機能はプロセスを終了させることですが、正常なプロセスをゾンビプロセスに変えるだけで完全に破壊することはできません。
Linux プロセスのステータスの中でも、ゾンビ プロセスは非常に特殊な種類で、ほとんどすべてのメモリ領域を放棄しており、実行可能なコードを持たず、プロセス リスト内の位置を記録するだけです。さらに、ゾンビ プロセスはメモリ領域を占有しなくなります。死体を収集するには親プロセスが必要です。
親プロセスが SIGCHLD シグナル処理関数をインストールせず、wait または waitpid() を呼び出して子プロセスの終了を待ち、シグナルを明示的に無視しない場合、親プロセスはゾンビ状態のままになります。プロセスはこの時点で終了し、その後 init プロセスは自動的に子プロセスを引き継ぎ、その死体を収集しますが、それでもクリアできます。
しかし、親プロセスがループしていて終了しない場合、子プロセスはゾンビ状態のままになるため、システム内に多くのゾンビプロセスが存在することがあります。システムが使用できるプロセス数には制限があります。大量のゾンビプロセスが生成されると、使用可能なプロセス数がなくなるため、システムは新しいプロセスを生成できなくなります。
3.ゾンビ プロセス
1. 親プロセスは、wait や waitpid などの関数を通じて子プロセスが終了するのを待ちます。これにより、親プロセスがハングします。 2. 親プロセスが非常にビジーな場合は、シグナル関数を使用できます。 SIGCHLD のハンドラーをインストールします。子プロセスが終了すると、親プロセスが受信するためです。このシグナルは、ハンドラー内で wait を呼び出すことでリサイクルできます
3. 親プロセスが子プロセスの終了を気にしない場合は、次を使用できます。 signal(SIGCHLD, SIG_IGN) を使用して、子プロセスの終了に関心がないことをカーネルに通知すると、子プロセスが終了します。その後、カーネルはリサイクルされ、親プロセスにシグナルを送信しなくなります
4.いくつかのトリック、つまり、フォークを 2 回行うと、親プロセスが子プロセスをフォークして動作を継続し、子プロセスが孫プロセスをフォークして終了し、孫プロセスが終了すると、プロセスが init によって引き継がれます。 、init がそれをリサイクルします。ただし、子プロセスのリサイクルは自分で行う必要があります。
子プロセスが終了後にゾンビ状態になるのはなぜですか?
親プロセスが子プロセスの終了ステータスやその他の情報を取得したい場合があるためです。
ゾンビ状態とは、各子プロセスが通過する状態ですか?
どの子プロセス(initを除く)も、exit()の直後には消滅せず、ゾンビプロセス(Zombie)構造と呼ばれるデータを残します(一部を占有します)。メモリ リソース (つまり、プロセス テーブルにレコードがまだ存在します) は、親プロセスによる処理を待っています。これは、すべての子プロセスが最後に通過する段階です。子プロセスが exit() の後に処理する時間がない場合は、ps コマンドを使用して、子プロセスのステータスが「Z」であることを確認できます。
親プロセスが時間内に処理できれば、ps コマンドを使用して子プロセスのゾンビ状態を確認するのは手遅れになる可能性がありますが、これは子プロセスがゾンビ状態を経ないという意味ではありません。
子プロセスが終了する前に親プロセスが終了した場合、子プロセスはinitに引き継がれます。 initはゾンビ状態の子プロセスを親プロセスとして処理します。
4. ゾンビプロセスを表示する方法
Linux では、コマンド ps を使用すると、Z とマークされたプロセスがゾンビプロセスであることがわかります。
ps -ef|grep defunc はゾンビプロセスを見つけることができます。
ps の -l オプションを使用すると、より詳細なプロセス情報を取得できます。 F (フラグ): 一連の数値の合計で、現在のステータスを示します。プロセス。これらの数字の意味は次のとおりです:
00: 単独で表示された場合、このプロセスが終了したことを意味します。
01: プロセスはコア プロセスの一部であり、システムのメイン メモリに常駐します。例: sched、vhand、bdflush など。 02:親はプロセスをトレースしています。
04:親のシグナルをトレースするとプロセスが停止しました。親は待機中です(ptrace(S))。
10:優先度が 25 以下の場合、プロセスはスリープ状態に入ります。 i ノードの作成を待機しているときなど、シグナルを使用してウェイクアップすることはできません
20: プロセスはメイン メモリ (一次メモリ) にロードされます
40: プロセスはメイン メモリにロックされており、プロセスが実行される前に置き換えることはできませんトランザクションが完了しました
S(プロセスの状態
B:プロセスはさらなるメモリページを待っています
C:CPU使用率(CPU使用率)の推定値
5. ゾンビプロセスをクリアする方法
1. 親プロセスを書き換えて、子プロセスの終了後に子プロセスの本体を収集します。具体的な方法は、SIGCHLD シグナルを引き継ぐことです。子プロセスが終了すると、SIGCHLD シグナルが親プロセスに送信され、このシグナルを受信した親プロセスは waitpid() 関数を実行して子プロセスの死体を収集します。これは、親プロセスが wait を呼び出さなくても、カーネルは親プロセスに SIGCHLD メッセージを送信するという原則に基づいていますが、このメッセージに応答したい場合は、処理関数を設定できます。 。
SIGCHLD シグナル: 子プロセスが終了すると、親プロセスがこのシグナルを受け取ります。親プロセスがこのシグナルを処理せず、子プロセスを待機しない場合、子プロセスは終了しても、カーネル プロセス テーブル内のエントリを占有したままになります。このとき、子プロセスはゾンビ プロセスと呼ばれます。この状況は回避する必要があります (親プロセスが SIGCHILD シグナルを無視するかキャッチするか、生成する子プロセスを待つか、親プロセスが最初に終了し、その後子プロセスの終了が init プロセスによって自動的に引き継がれます) )。
2. kill -18 PPID (PPIDは親プロセスです)
このシグナルは、子プロセスが終了したので、割り当てられていたリソースを取り戻してくださいと親プロセスに伝えます。
SIGCONTも興味深いシグナルです。前述したように、プロセスが停止すると、このシグナルはプロセスに実行を再開するように指示するために使用されます。この信号の興味深い点は、無視したりブロックしたりすることはできませんが、キャッチすることはできるということです。デフォルトの動作では、信号が破棄されます。
3. 親プロセスを終了する
方法2が終了できない場合は、その親プロセスを終了する方法を使用できます(親プロセスが終了すると、ゾンビプロセスは「孤立」になります。) init、init は常にゾンビプロセスのクリーンアップを担当します。それが生成したすべてのゾンビプロセスも消えました。
まず、親プロセス内に他の子プロセスがないかどうかを確認し、存在する場合は、最初に他の子プロセス、つまり兄弟プロセスを強制終了する必要があるかもしれません。方法は、
Kill –15 PID1 PID2 (PID1とPID2はゾンビプロセスの親プロセスの他の子プロセス)です。
次に、親プロセスをkillします: kill –15 PPID
このようにして、ゾンビプロセスを完全にkillすることができます。
Linux でゾンビ プロセスに対処する方法に関するその他の関連記事については、PHP 中国語 Web サイトに注目してください。