Linuxでゾンビプロセスを強制終了する方法
公開: 2022-01-29プログラムの記述が不十分であるか、パフォーマンスが悪いと、ゾンビプロセスがLinuxコンピューター内に潜んでいる可能性があります。 ゾンビがどのように作成されるか、そして最終的にゾンビを休ませることができる方法をご覧ください。
Linuxでプロセス状態がどのように機能するか
もちろん、Linuxは、コンピューターで実行されているすべてのアプリケーションとデーモンを追跡する必要があります。 これを行う方法の1つは、プロセステーブルを維持することです。 これは、カーネルメモリ内の構造のリストです。 各プロセスには、このリストにいくつかの情報を含むエントリがあります。
各プロセステーブル構造にはそれほど多くはありません。 これらは、プロセスID、その他のいくつかのデータ項目、およびそのプロセスのプロセス制御ブロック(PCB)へのポインターを保持します。
Linuxがプロセスごとに検索または設定する必要のある多くの詳細を保持しているのはPCBです。 PCBは、プロセスが作成され、処理時間が与えられ、最終的に破棄されるときにも更新されます。
Linux PCBには、95を超えるフィールドが含まれています。 これはtask_struct.h
と呼ばれる構造体として定義されており、700行を超えています。 PCBには、次の種類の情報が含まれています。
- プロセス状態:状態は以下のとおりです。
- プロセス番号:オペレーティングシステム内の一意の識別子。
- プログラムカウンター:このプロセスに次にCPUへのアクセスが許可されると、システムはこのアドレスを使用して、実行する必要のあるプロセスの次の命令を検索します。
- レジスター:このプロセスで使用されるCPUレジスターのリスト。 リストには、アキュムレータ、インデックスレジスタ、およびスタックポインタが含まれる場合があります。
- ファイルリストを開く:このプロセスに関連するファイル。
- CPUスケジューリング情報:このプロセスにCPU処理時間が与えられる頻度と期間を決定するために使用されます。 プロセスの優先度、スケジューリングキューへのポインタ、およびその他のスケジューリングパラメータをPCBに記録する必要があります。
- メモリ管理情報:プロセスメモリの開始アドレスと終了アドレス、メモリページへのポインタなど、このプロセスが使用しているメモリに関する詳細。
- I / Oステータス情報:プロセスで使用される入力デバイスまたは出力デバイス。
「プロセス状態」は、次のいずれかになります。
- R:実行中または実行可能なプロセス。 実行中とは、CPUサイクルを受信して実行していることを意味します。 実行可能なプロセスを実行する準備ができており、CPUスロットを待機しています。
- S:睡眠プロセス。 プロセスは、入力または出力操作などのアクションが完了するのを待っているか、リソースが使用可能になるのを待っています。
- D:プロセスは中断できないスリープ状態にあります。 ブロッキングシステムコールを使用しており、システムコールが完了するまで続行できません。 「スリープ」状態とは異なり、この状態のプロセスは、システムコールが完了し、実行がプロセスに戻るまで、シグナルに応答しません。
- T:
SIGSTOP
信号を受信したため、プロセスは終了(停止)しました。 プロセスを強制終了するか、続行するように指示するSIGKILL
またはSIGCONT
シグナルにのみ応答します。 これは、フォアグラウンド(fg
)タスクからバックグラウンド(bg)
タスクに切り替えるときに発生することです。 - Z:ゾンビプロセス。 プロセスが完了すると、それはただ消えるだけではありません。 使用しているメモリを解放し、メモリから削除しますが、プロセステーブルとPCBのエントリは残ります。 その状態は
EXIT_ZOMBIE
に設定され、その親プロセスは子プロセスが終了したことを(SIGCHLD
シグナルによって)通知されます。
ゾンビ状態では、子プロセスが作成されるときに、親プロセスが関数のwait()
ファミリの1つを呼び出します。 次に、子プロセスの状態変化を待ちます。 子プロセスは、シグナルによって停止、継続、または強制終了されましたか? コードの自然な完成を実行することで終了しましたか?
状態の変化が子プロセスの実行を停止したことを意味する場合、その終了コードが読み取られます。 次に、子のPCBが破棄され、プロセステーブルのエントリが削除されます。 理想的には、これはすべて瞬く間に発生し、ゾンビ状態のプロセスは非常に長い間存在しません。
関連: Linuxでバックグラウンドプロセスを実行および制御する方法
Linuxでゾンビプロセスが発生する原因は何ですか?
不適切に記述された親プロセスは、子プロセスの作成時にwait()
関数を呼び出さない場合があります。 これは、子プロセスの状態変化を監視しているものがなく、 SIGCHLD
シグナルが無視されることを意味します。 または、プログラミングが不十分であるか悪意があるために、別のアプリケーションが親プロセスの実行に影響を与えている可能性があります。
ただし、親プロセスが子プロセスの状態変化を監視していない場合、適切なシステムハウスキーピングは行われません。 子プロセスが終了しても、PCBとプロセステーブルのエントリは削除されません。 これにより、ゾンビ状態がPCBから削除されることはありません。
ゾンビは少しのメモリを使用しますが、通常は問題を引き起こしません。 プロセステーブルのエントリは小さいですが、リリースされるまで、プロセスIDを再利用することはできません。 64ビットオペレーティングシステムでは、PCBがプロセステーブルエントリよりもはるかに大きいため、問題が発生する可能性はほとんどありません。
膨大な数のゾンビが、他のプロセスのために解放されるメモリの量に影響を与える可能性があります。 ただし、ゾンビがたくさんいる場合は、親アプリケーションに深刻な問題があるか、オペレーティングシステムのバグがあります。
ゾンビプロセスを削除する方法
ゾンビプロセスはすでに死んでいるため、殺すことはできません。 メモリから削除されているため、シグナルに応答しませんSIGKILL
を送信する場所がありません。 SIGCHLD
シグナルを親プロセスに送信してみることができますが、子プロセスが終了したときにそれが機能しなかった場合は、現在も機能しない可能性があります。
唯一の信頼できる解決策は、親プロセスを強制終了することです。 終了すると、その子プロセスは、Linuxシステムで実行される最初のプロセスであるinit
プロセスに継承されます(プロセスIDは1です)。
init
プロセスは、ゾンビの必要なクリーンアップを定期的に実行するため、ゾンビを強制終了するには、ゾンビを作成したプロセスを強制終了する必要があります。 top
コマンドは、ゾンビがいるかどうかを確認するための便利な方法です。
次のように入力します。
上
このシステムには8つのゾンビプロセスがあります。 ps
コマンドを使用してegrep
にパイプすることで、これらを一覧表示できます。 繰り返しになりますが、ゾンビプロセスには「Z」の状態フラグがあり、通常は「defunct」も表示されます。
次のように入力します。
ps aux | egrep "Z | defunct"
ゾンビプロセスが一覧表示されます。
これは、 top
を前後にスクロールするよりも、ゾンビのプロセスIDを見つけるための優れた方法です。 また、「badprg」と呼ばれるアプリケーションがこれらのゾンビを生成したこともわかります。
最初のゾンビのプロセスIDは7641ですが、その親プロセスのプロセスIDを見つける必要があります。 もう一度
を使用することでこれを行うことができます。 出力オプション( ps
-o
)を使用して、親のプロセスIDのみを表示するようにps
に指示し、 ppid=
フラグを付けて渡します。
検索するプロセスは、 -p
(プロセス)オプションを使用して示され、ゾンビのプロセスIDを渡します。
したがって、次のコマンドを入力してプロセス7641のプロセス情報を検索しますが、レポートされるのは親プロセスのIDのみです。
ps -o ppid = -p 7641
親プロセスIDは7636であると言われています。これで、もう一度ps
を使用してこれを相互参照できます。
これは、以前の親プロセスの名前と一致していることがわかります。 親プロセスを強制終了するには、次のようにkillコマンドでSIGKILLオプションを使用します。
殺す-SIGKILL7636
親プロセスの所有者によっては、 sudo
を使用する必要がある場合もあります。
ゾンビは怖くない…
…彼らが大群にいない限り。 いくつかは心配する必要はなく、単純な再起動でそれらが一掃されます。
ただし、アプリケーションまたはプロセスが常にゾンビを生成していることに気付いた場合は、それを調べる必要があります。 ほとんどの場合、プログラムはだらしなく作成されています。その場合は、子プロセスの後に適切にクリーンアップされる更新バージョンが存在する可能性があります。