SIGKILLシグナルを送信したプログラムは何をしますか?


39

私が使用した場合killall -9 name、プログラムを殺すために、状態がゾンビになります。数分後、本当に止まりました。それで、その数分間に何が起きているのでしょうか?

回答:


66

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

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

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

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

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

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

親プロセスが子プロセスの前に停止した場合、孤立した子プロセスは自動的にPID#1に採用されますwait(2)

ゾンビプロセスがクリアされるのに数分かかる場合は、ゾンビのプロセスが悪戦苦闘しているか、ジョブを適切に実行していないことを示唆しています。

Unixライクなオペレーティングシステムでゾンビの問題が発生した場合の対処方法については、「ゾンビ自体はすでに死んでいるので、何もできません。代わりに、邪悪なゾンビマスターを殺してください」という言葉があります。(つまり、面倒なゾンビの親プロセス)


5
SIGKILLが送信されたときに、プロセスがカーネル呼び出し(たとえば、I / Oを実行している)の場合はどうなりますか?
gidds

9
@gidds SIGKILLを実行するためにI / Oがキャンセルされるか、SIGKILLはI / Oが完了するまで遅延されます。これは、「S」と「D」のスリープ状態の違いですps。「S」は、シグナルを配信するためにカーネルがキャンセルできるI / O待機を表し、「D」は、配信できないものを表します。
zwol

6
スケジュールがすぐにプロセスCPU時間の提供を停止すると言うのは完全に正確ではありません。シグナル処理のカーネル側はまだそのプロセスによって実行されますが、プロセスはカーネルコードのみを実行するため、プログラムがシグナルを受信しないと言うのはあなたです。プロセスは、リソース(オープンファイル、仮想メモリなど)のほとんどのクリーンアップを行うカーネルコードを実行します。このクリーンアップコードの最後の手順は、プロセスの状態をゾンビに変更し、スケジューラーを呼び出すことです。その後、再びスケジュールされることはありません。
カスペルド

4
@giddsプロセスには、少なくとも4つの異なる状態があります。現時点でカーネルコードを実行している場合と、3つの異なるスリープ状態のいずれかでスリープしている場合があります。スリープ状態は、致命的な信号を除き、割り込み可能、​​割り込み不可、または割り込み不可のいずれかです。割り込み不可能なスリープ状態にある場合は、必要な限りスリープ状態のままになり、一度目覚めると死ぬ可能性があります。他の2つのスリープ状態のいずれかであった場合、すぐに起動され、使用可能なCPUがあるとすぐにスケジュールされます。
カスペルド

2
@gidds次に何が起こるかは、実行していたカーネルコードによって異なります。すでに実行されていたかどうかに関係なく、最初に起動してからその時点でカーネルコードの実行を開始する必要があったかどうかは、続行できます。そして、そのカーネルコードは、プロセスが停止し、それに応じて動作するように指示されたことに気付く責任があります。ほとんどの場合、カーネルコードでそれを処理する適切な方法は、実行中の関数からエラーを返すことです。カーネル呼び出しスタックが解かれると、シグナル処理コードがユーザーモードに戻る直前に引き継ぐことができます。
カスペルド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.