回答:
割り込み不可能なプロセスとは、シグナルによって割り込みできないシステムコール(カーネル関数)にあるプロセスです。
これが何を意味するのかを理解するには、割り込み可能なシステムコールの概念を理解する必要があります。典型的な例はread()
です。これは、ハードドライブのスピンアップやヘッドの移動を伴う可能性があるため、長い時間(数秒)かかるシステムコールです。この時間のほとんどの間、プロセスはスリープ状態になり、ハードウェアでブロックされます。
システムコールでプロセスがスリープしている間、プロセスはUnix非同期シグナル(たとえば、SIGTERM)を受信でき、次のことが起こります。
システムコールから早期に戻ると、ユーザー空間コードは信号に応答してその動作をすぐに変更できます。たとえば、SIGINTまたはSIGTERMに反応してクリーンに終了します。
一方、一部のシステムコールは、この方法で割り込みを許可されていません。システムが何らかの理由でストールを呼び出すと、プロセスはいつまでもこの強制不能状態のままになる可能性があります。
LWNはこのトピックに触れた素晴らしい記事を7月に掲載しました。
元の質問に答えるには:
これを防ぐ方法:問題の原因となっているドライバーを特定し、使用を停止するか、カーネルハッカーになって修正します。
再起動せずに無停止のプロセスを強制終了する方法:どういうわけかシステムコールを終了させます。電源スイッチを押すことなくこれを行う最も効果的な方法は、電源コードを抜くことです。LWNの記事で説明されているように、カーネルハッカーになり、ドライバにTASK_KILLABLEを使用させることもできます。
プロセスがユーザーモードの場合、いつでも中断できます(カーネルモードに切り替えます)。カーネルがユーザーモードに戻ると、保留中のシグナル(SIGTERM
andのようなプロセスを強制終了するために使用されるシグナルを含む)があるかどうかを確認しますSIGKILL
。これは、ユーザーモードに戻ったときにのみプロセスを強制終了できることを意味します。
カーネルモードでプロセスを強制終了できないのは、同じマシン内の他のすべてのプロセスで使用されているカーネル構造を破壊する可能性があるためです(スレッドを強制終了すると、同じプロセス内の他のスレッドで使用されているデータ構造が破損する可能性があります)。 。
カーネルが長い時間を必要とする何かを行う必要がある場合(別のプロセスによって書き込まれたパイプで待機したり、ハードウェアが何かを実行するのを待機したりするなど)、それ自体をスリープとしてマークし、スケジューラを呼び出して別のスケジューラに切り替えます。プロセス(非スリーププロセスがない場合、「ダミー」プロセスに切り替わり、CPUに少しスローダウンしてループ(アイドルループ)に入るように指示します)。
シグナルがスリープ中のプロセスに送信された場合、ユーザー空間に戻って保留中のシグナルを処理する前に、シグナルを起こさなければなりません。ここでは、2つの主なタイプの睡眠の違いがあります。
TASK_INTERRUPTIBLE
、割り込み可能なスリープ。タスクがこのフラグでマークされている場合、タスクはスリープ状態ですが、シグナルによって起こされる可能性があります。これは、タスクをスリープ状態としてマークしたコードがシグナルの可能性を期待しており、ウェイクアップした後、それをチェックしてシステムコールから戻ることを意味します。シグナルが処理された後、システムコールは自動的に再起動される可能性があります(その仕組みについては詳しく説明しません)。TASK_UNINTERRUPTIBLE
、途切れない睡眠。タスクがこのフラグでマークされている場合、簡単に再起動できないか、プログラムがシステムコールがアトミックであることをプログラムが期待しているため、待機しているもの以外のものによって起こされることを期待していません。これは、非常に短いことがわかっている睡眠にも使用できます。TASK_KILLABLE
(ddaaの回答でリンクされているLWNの記事で言及されている)は新しいバリアントです。
これはあなたの最初の質問に答えます。2番目の質問については、中断のないスリープを回避することはできません。これらは正常な状態です(たとえば、プロセスがディスクに対して読み取り/書き込みを行うたびに発生します)。ただし、それらはほんの一瞬しか続かないはずです。それらがはるかに長く続く場合、それは通常、ハードウェアの問題(またはカーネルに同じように見えるデバイスドライバーの問題)を意味し、デバイスドライバーはハードウェアが決して起こらない何かを実行するのを待っています。また、NFSを使用していて、NFSサーバーがダウンしていることも意味します(サーバーが回復するのを待っています。「intr」オプションを使用して問題を回避することもできます)。
最後に、回復できない理由は、カーネルがユーザーモードに戻って信号を送信するかプロセスを強制終了するまで待機するのと同じ理由です:カーネルのデータ構造が破損する可能性があります(割り込み可能なスリープで待機しているコードは、それを通知するエラーを受け取る可能性がありますプロセスが強制終了される可能性があるユーザー空間に戻る場合;中断のないスリープで待機しているコードはエラーを予期していません)。
通常、割り込み不可能なプロセスは、ページフォールトに続くI / Oを待機しています。
このことを考慮:
シグナルを処理できないため、この状態ではプロセス/タスクを中断できません。そうした場合、別のページ違反が発生し、元の場所に戻ります。
私が「プロセス」と言うとき、私は本当に「タスク」を意味します。これは、Linux(2.6)では、おおまかに「スレッド」に変換され、/ procに個別の「スレッドグループ」エントリがある場合とない場合があります。
しばらくお待ちいただく場合があります。この典型的な例は、実行可能ファイルまたはmmapされたファイルが、サーバーに障害が発生したネットワークファイルシステム上にある場合です。I / Oが最終的に成功した場合、タスクは続行されます。最終的に失敗すると、タスクは通常SIGBUSまたは何かを取得します。
「ゾンビ」プロセス(ps出力では「ゾンビ」と指定されている)について話している場合、これはプロセスリスト内の無害なレコードであり、誰かが戻りコードを収集するのを待っているため、無視しても安全です。
「中断のないプロセス」とは何ですか?それは「キル-9」を生き延びて、幸せに一緒に食べますか?その場合は、一部のシステムコールで停止しており、一部のドライバーで停止しており、再起動するまで(そして、場合によってはすぐに再起動する方がよい場合があります)、または関連するドライバーのアンロード(発生する可能性が低い)まで、このプロセスで停止します。 。"strace"を使用して、プロセスがどこに行き詰まっているのかを調べ、将来それを回避することができます。
TASK_UNINTERUPTIBLE
システムがアイドル状態でないときにいつでも状態になるプロセスを開始するプログラムを作成して、スーパーユーザーが終了すると強制的にデータを収集し、送信を待機することは可能ですか?これは、ハッカーが情報を取得し、ゾンビ状態に戻り、アイドル時にネットワークを介して情報を送信するための金鉱となります。これはBlackdoor
、必要に応じてシステムに出入りするための権限を作成する1つの方法であると主張する人もいます。この抜け穴は、 `TASK_UNINTERUPTIB