killall -9 name
を使用したとき プログラムを殺すために、状態はゾンビになります。数分後、それは本当に止まりました。
では、その数分間に何が起こったのでしょうか?
承認された回答:
SIGKILLはオペレーティングシステム/カーネルによって完全に処理されるため、プログラムは実際にはSIGKILLシグナルを受信しません。
特定のプロセスのSIGKILLが送信されると、カーネルのスケジューラはすぐにそのプロセスにユーザースペースコードを実行するためのCPU時間を与えるのを停止します。スケジューラーがこの決定を行うときに、プロセスに他のCPU /コアでユーザースペースコードを実行するスレッドがある場合、それらのスレッドも停止されます。 (シングルコアシステムでは、これは以前ははるかに単純でした。システム内の唯一のCPUコアがスケジューラーを実行していた場合、定義上、同時にプロセスを実行していませんでした!)
プロセス/スレッドがSIGKILLの時点でカーネルコード(システムコールやメモリマップトファイルに関連付けられたI / O操作など)を実行している場合は、少し注意が必要です。一部のシステムコールのみが割り込み可能であるため、カーネルは、システムコールまたはI / O操作が解決されるまで、プロセスを特別な「死にかけている」状態として内部的にマークします。それらを解決するためのCPU時間は、通常どおりにスケジュールされます。割り込み可能なシステムコールまたはI/O操作は、それらを呼び出したプロセスが適切な停止ポイントで停止しているかどうかを確認し、その場合は早期に終了します。中断のない操作は完了し、ユーザースペースコードに戻る直前に「死にかけている」状態をチェックします。
インプロセスカーネルルーチンが解決されると、プログラムが正常に終了する場合と同様に、プロセス状態が「dying」から「dead」に変更され、カーネルがクリーンアップを開始します。クリーンアップが完了すると、128を超える結果コードが割り当てられ(プロセスがシグナルによって強制終了されたことを示します。詳細については、この回答を参照してください)、プロセスは「ゾンビ」状態に移行します。 。強制終了されたプロセスの親には、SIGCHLDシグナルが通知されます。
その結果、プロセス自体が、SIGKILLを受け取った情報を実際に処理する機会を得ることができなくなります。
プロセスが「ゾンビ」状態にある場合、プロセスはすでに停止していることを意味しますが、その親プロセスは、wait(2)
を使用して停止しているプロセスの終了コードを読み取ることにより、これをまだ確認していません。 システムコール。基本的に、ゾンビプロセスがこれ以上消費している唯一のリソースは、プロセステーブル内のスロットであり、そのPID、終了コード、およびプロセスの終了時のその他の「人口動態統計」を保持します。
親プロセスが子プロセスの前に停止した場合、孤立した子プロセスはPID#1によって自動的に採用されます。これには、wait(2)
を呼び出し続けるという特別な義務があります。 孤立したプロセスがゾンビとして立ち往生しないようにします。
ゾンビプロセスがクリアされるまでに数分かかる場合は、親 ゾンビのプロセスが苦労しているか、適切に機能していません。
Unixライクなオペレーティングシステムでゾンビの問題が発生した場合の対処方法については、次のような説明があります。「ゾンビはすでに死んでいるため、ゾンビ自体に対しては何もできません。代わりに、邪悪なゾンビマスターを殺してください! 」(つまり、厄介なゾンビの親プロセス)