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





