Windowsは、プログラムが応答していないかどうかをどのように知るのですか?


174

Windowsは、プログラムが応答していないかどうかをどのように知るのですか?実行中のすべてのアプリケーションを常にポーリングし続けますか?



@ magicandre1981このページは、プログラムが何かを積極的に実行していることを確認する1つの方法を提案していますが、Windowsが実際に使用している方法ではありません。
ケビンパンコ

Windowsメッセージキューを見て、候補のPeekMessage()関数である
ルチアーノ

回答:


150

アプリケーションは、Windowsが提供するキューからイベントを取得します。

長い計算を行う場合など、アプリケーションがしばらく(5秒)イベントキューをポーリングしない場合、Windowsはアプリケーションがハングしているとみなし、ユーザーに警告します。

アプリケーションがそれを回避するには、高価な計算をワーカースレッドにプッシュするか、処理を分割して、キューが定期的にポーリングされるようにする必要があります。


27
↑これ。スケジューリングや、受け入れられた回答で提案されているようなこととは関係なく、定期的にGetMessage(または同様の)およびを呼び出すかどうかのみDispatchMessage
デイモン

1
受け入れられた答えIsHungAppWindowは、起動フェーズのプログラムがを呼び出す必要がないことを正しく言及していることに言及していますGetMessage
–MSalters

@MSaltersスタートアップが最初の前の時間として定義されていGetMessageますか?この機能により、単純なコマンドラインアプリは、キューをポーリングする必要がないため、ハングしていると見なされることなく動作します。
ラチェットフリーク

4
@ratchetfreak:おそらく最初のCreateWindow呼び出しの前。コマンドラインアプリはまったく別物です。それらはConHost.EXE内で実行されており、Windows GUI susbystemと対話します。
–MSalters

1
また、Windows 7(および場合によってはそれ以前)では、何らかの方法でウィンドウを操作しようとして失敗すると、ウィンドウがこれに早く気付くようです。プログラムが最大化を処理したり、メッセージを移動していない場合は、Windows 7は、約1または2秒後に応答しない権利をジャンプします。..のような
デイブCousineau

78

Windowsは、プログラムが応答していないかどうかをどのように知るのですか?

Windowsへのソースコードがないと、内部で何をしているのかを確認できません。

IsHungAppWindow使用できるSDK Windows関数があります。

アプリケーションは、入力を待機しておらず、起動処理中ではなく、5秒の内部タイムアウト期間内にPeekMessageを呼び出していない場合、応答していないと見なされます。

ソースIsHungAppWindow関数

最上位ウィンドウが数秒以上メッセージに応答しなくなった場合、システムはウィンドウが応答していないと見なします。この場合、システムはウィンドウを非表示にし、同じZオーダー、位置、サイズ、および視覚属性を持つゴーストウィンドウに置き換えます。これにより、ユーザーはそれを移動、サイズ変更、またはアプリケーションを閉じることができます。ただし、アプリケーションが実際に応答していないため、これらは利用可能な唯一のアクションです。

メッセージとメッセージキューについてのソース


実行中のすべてのアプリケーションを常にポーリングし続けますか?

いいえ。アプリケーションはポーリングされませんが、プロセッサ時間が与えられます。

Windowsには、アプリケーションスレッドにプロセッサ時間を与えるスケジューリングシステムがあります。

スケジューリングアルゴリズムは複雑で、Windows Internals、パート1(第6版)(開発者向けリファレンス)で詳しく説明されています


2
ハング状態はCPUに基づいていません。ほとんどのプログラムは、その意味で99.999%の時間「ハング」しており、何もしません。
usr

2
@usr「ハング」はCPUに依存するとどこで言いましたか?
DavidPostill

2
@usr答えの前半は、「実行中のすべてのアプリケーションを常にポーリングし続けますか?」という答えです。後半はOPが一つに二つの質問を尋ねた?。プログラムが応答しない場合、どのようWindowsが知っている」の回答されます。)
DavidPostill

9
しかし、実際にはポーリングではありませんか?内部は、呼び出し時にウィンドウの待機ハンドルに信号が送られるようなものだと思いますPeekMessage。そのため、Windowsがアプリケーションにメッセージを送信し、5秒以内に信号が送られない場合、アプリケーションが応答していないとマークします。実際、最近のWindowsでは、ウィンドウはユーザー入力に時間内に応答しなかった場合にのみ「応答なし」とマークされます。キーまたは何かをクリックするか押すまで、アプリケーションは応答しない「表示」なしで数分。
ルアーン

2
答えに役立たないため、「メッセージとメッセージキューについて」の上のすべてを削除できます。Windowsは、メッセージの送信を停止するため、アプリが応答を停止したことを認識しています。ただし、メッセージをポンピングするのではなく、集中的な処理を行うため、アプリを実行できます(ただし、設計が不十分なプログラムです)。
アンディ

32

実際、Windowsはアプリケーションが応答していないことを常に認識しているわけではありません。アプリケーションは、ウィンドウを備えた対話型アプリケーションである必要があり、ウィンドウは、アプリケーションが応答していないとWindowsが判断する前に、アプリケーションが処理に失敗したというメッセージを受信する必要があります。

たとえば、Windowsには、コマンドラインから実行されるユーザーインターフェイスを持たない数値演算アプリケーションが機能しているのか、無限ループに陥っているのかを知る方法がありません。

Windowsの対話型グラフィカルアプリケーションは、メッセージキューを継続的にポーリングすることによりイベントを受信します。Windowsは、このメッセージキューにキーボード、マウス、タイマーなどのイベントを追加します。アプリケーションがメッセージキューのポーリングにしばらく失敗した場合(IsHungAppWindow()関数のドキュメントに記載されているタイムアウトは5秒です)、Windowsはアプリケーションを「ハング」したと見なします。 (応答なし)」またはローカライズ版の同等のテキスト)、ユーザーがウィンドウを操作しようとするとウィンドウのコンテンツがグレー表示されます。

Windowsが認識しない方法でアプリケーションがハングする可能性があります。たとえば、アプリケーションはメッセージキュー内のメッセージを適切に処理せずにポーリングし続けることがあるため、すべての実用的な意図と目的に対して、Windowsが応答しないことを認識せずに「ハング」しているように見えます。


8
定義上、応答しないということは、ウィンドウメッセージを処理しないことを意味するため、サービスやコンソールアプリには適用されません。デッドロックを混乱させ、応答しません。
アンディ

もちろん、プログラムが応答していないかどうかを知ることができます。「応答なし」「無限ループに陥っ」と同じではありません
BlueRaja -ダニーPflughoeft

1
実際には、アプリケーションはGetMessage()を介してメッセージを取得し、それらの処理に失敗する可能性があります。また、ユーザーに対して応答しないように見えるにもかかわらず、Windowsによって「応答なし」として認識されません。「応答しない」という用語は、ネットワーク、サービス、対話型コマンドラインなどのアプリケーションを表すためにもよく使用されます。知る限りでは、フレーズをウィンドウアプリケーションに限定する正式な定義はありません。デッドロックまたは無限ループ(またはその他のプログラミングエラー)の両方により、アプリケーションが応答しなくなることがありますが、原因と結果を混同しませんでした。
ビクトルトス

10

Windowsはオペレーティングシステムであり、実行中のすべてのプログラムを監視します。

Windowsは、イベントを使用してウィンドウベースのアプリケーションと通信します。すべてのプログラムには、着信イベントを常にリッスンして処理するスレッドがあります。たとえば、ボタンまたは通知領域のアイコンをクリックすると、Windowsはイベントを生成し、適切なプロセスにフィードします。その後、プロセスはその処理方法を決定できます。

Windowsでは、プログラムとのやり取りはすべてイベントベースです。したがって、プログラムが受信イベントを長時間処理しない場合、応答しません。@DavidPostillが彼の答えで見つけて指摘しように、タイムアウトは5秒です。PeekMessageイベントキューからイベントを取得する関数です。


0

あなたの質問に対する答えはイエス/ノーです。

Windows OSはWindows Messaging Queueのイベントを使用してアプリケーションをポーリングできますが、プログラムはWinAPIにリンクしたり、Windows Queueを処理/応答したりする義務はまったくありません。キュー内のメッセージに応答しても、プログラムが「ロックアップ」したかどうかをWindowsに通知しません。これはインジケータですが、それだけです。本当の答えはかなり複雑です。

本当の答え

人々はここで実際の答えを回避しています。プログラムが「応答しない」かどうかを判断することは、「停止する問題」の変形であり、コンピューターサイエンスでは正式に決定できません。簡単な説明としては、プロセッサは、サブルーチンが無限ループでスタックしているかどうかを判断するサードパーティとして動作することはできません。これらは両方とも、緊密に閉じたループと見なすことができます。一方が停止し、もう一方が終了することはありません。でももし、人として、それはしっかりと閉ループである場合は特に、プログラムが実際に応答するかしないかどうかわからない-場合にのみ知っている、それはすべきだと思う(対応)。

Windowsから見ると、これらのループは両方とも「応答していません」。そのため、Windowsは待機するか終了するかを選択できます。

その結果、「プロセス応答していることをWindowsが知っているのはなぜですか?」答えはかなり賢いです。プロセスがマルチスレッドおよびマルチプロセスOSでコンパイルされる場合、場合によっては緊密に閉じたループでも、コンパイラーはyield()コマンドを追加する場合があります。これにより、実行中の他のプロセスに切り替えることができるという便利な通知がプロセッサーに提供されます。プロセッサを「解放」し、OSがスタック内の他のイベントに応答できる「コンテキストスイッチ」(呼び出されたとおりに)が発生し、その中にはプロセス応答した追跡が含まれます。

**これは、応答するプロセスが終了することを意味するものではありません。**無限ループ内のプロセスはプロセッサを生成し、Windowsが他のイベントを処理できるようにします。

一部のWindowsプログラムでは、プログラムがWindows OS信号を処理し、OSに「応答」していることを伝えることができますが、それを行う義務のあるプログラムはありません。perl、php、pythonなどのWindowsの高レベル言語の中でも、非常に単純なCPUホグ、非終了プログラムを書くことができます。その時点で、Windowsはヒューリスティックに依存しています-CPU負荷、メモリ、プログラムが「推測」するために実行されている間にプロセッサが処理した割り込みの数。繰り返しますが、その時点で、Windowsは終了すべきかどうかを尋ねなければなりません。

Viktorの(正しい)回答も参照してください。「応答しない」が無限ループと同じではないかどうかについてのコメントを無視します。Windowsメッセージキューに通知せずにアプリケーションが処理する場合もしない場合もある、あらゆる種類のメッセージ、割り込み、ループがあります。メッセージキューの処理は、プロセスがハングしているかどうかを推測するためにOSがカウンターを保持する多くの種類のイベントの1つにすぎません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.