web-dev-qa-db-ja.com

SIGKILLシグナルが送信されたとき、プログラムは何をしますか?

killall -9 nameプログラムを強制終了すると、状態はゾンビになります。数分後、本当に止まりました。それで、それらの分の間何が起こっているのですか?

40
haikun he

SIGKILLはオペレーティングシステム/カーネルによって完全に処理されるため、プログラムは実際にはSIGKILLシグナルを受信しません。

特定のプロセスのSIGKILLが送信されると、カーネルのスケジューラは直ちに停止して、そのプロセスにユーザー空間コードを実行するためのCPU時間を与えます。スケジューラがこの決定を行ったときに、プロセスが他のCPU /コアでユーザー空間コードを実行するスレッドを持っている場合、それらのスレッドも停止されます。 (シングルコアシステムでは、以前はこれがはるかに単純でした。システム内の唯一のCPUコアがスケジューラを実行している場合、当然ながら、同時にプロセスを実行していませんでした。)

プロセス/スレッドがSIGKILLの時点でカーネルコード(たとえば、システムコール、またはメモリマップトファイルに関連付けられたI/O操作)を実行している場合、少しトリッキーになります。一部のシステムコールのみが割り込み可能であるため、カーネルは、システムコールまたはI/O操作が解決されるまで、プロセスを内部的に特別な「死にかけている」状態としてマークします。それらを解決するためのCPU時間は通常どおりにスケジュールされます。割り込み可能なシステムコールまたはI/O操作は、それらを呼び出したプロセスが適切な停止ポイントで終了しているかどうかをチェックし、その場合は早期に終了します。無停止の操作は完了するまで実行され、ユーザー空間コードに戻る直前に「死にかけている」状態をチェックします。

インプロセスカーネルルーチンが解決されると、プログラムの正常終了時と同様に、プロセスの状態が「死にかけている」から「デッド」に変わり、カーネルがクリーンアップを開始します。クリーンアップが完了すると、128を超える結果コードが割り当てられます(プロセスがシグナルによって強制終了されたことを示すために 乱雑な詳細についてはこの回答を参照 )、およびプロセス「ゾンビ」状態に移行します。強制終了されたプロセスの親は、SIGCHLDシグナルで通知されます。

その結果、プロセス自体は、SIGKILLを受け取った情報を実際に処理する機会を得ることは決してありません。

プロセスが「ゾンビ」状態にある場合、それはプロセスがすでに停止していることを意味しますが、その親プロセスは、wait(2)システムコールを使用して、停止したプロセスの終了コードを読み取ることによってまだ確認していません。基本的に、ゾンビプロセスがこれ以上消費している唯一のリソースは、プロセステーブルのスロットで、そのPID、終了コード、およびプロセスが終了したときのその他の「重要な統計」が保持されます。

親プロセスがその子の前に停止した場合、孤立した子プロセスはPID#1によって自動的に採用されます。PID#1は、孤立したプロセスがゾンビとして留まらないようにwait(2)を呼び出し続ける特別な義務があります。

ゾンビプロセスがクリアされるまで数分かかる場合は、ゾンビのparentプロセスが苦労しているか、適切に機能していないことを示しています。

Unixライクなオペレーティングシステムでゾンビの問題が発生した場合の対処法については、「口の内の説明」があります。「ゾンビはすでに死んでいるので、自分で何もすることはできません。代わりに邪悪なゾンビのマスターを殺せ! "(つまり、厄介なゾンビの親プロセス)

68
telcoM