回答:
アプリケーションは、Windowsが提供するキューからイベントを取得します。
長い計算を行う場合など、アプリケーションがしばらく(5秒)イベントキューをポーリングしない場合、Windowsはアプリケーションがハングしているとみなし、ユーザーに警告します。
アプリケーションがそれを回避するには、高価な計算をワーカースレッドにプッシュするか、処理を分割して、キューが定期的にポーリングされるようにする必要があります。
GetMessage
(または同様の)およびを呼び出すかどうかのみDispatchMessage
。
IsHungAppWindow
は、起動フェーズのプログラムがを呼び出す必要がないことを正しく言及していることに言及していますGetMessage
。
GetMessage
ますか?この機能により、単純なコマンドラインアプリは、キューをポーリングする必要がないため、ハングしていると見なされることなく動作します。
Windowsへのソースコードがないと、内部で何をしているのかを確認できません。
IsHungAppWindow
使用できるSDK Windows関数があります。
アプリケーションは、入力を待機しておらず、起動処理中ではなく、5秒の内部タイムアウト期間内にPeekMessageを呼び出していない場合、応答していないと見なされます。
最上位ウィンドウが数秒以上メッセージに応答しなくなった場合、システムはウィンドウが応答していないと見なします。この場合、システムはウィンドウを非表示にし、同じZオーダー、位置、サイズ、および視覚属性を持つゴーストウィンドウに置き換えます。これにより、ユーザーはそれを移動、サイズ変更、またはアプリケーションを閉じることができます。ただし、アプリケーションが実際に応答していないため、これらは利用可能な唯一のアクションです。
いいえ。アプリケーションはポーリングされませんが、プロセッサ時間が与えられます。
Windowsには、アプリケーションスレッドにプロセッサ時間を与えるスケジューリングシステムがあります。
スケジューリングアルゴリズムは複雑で、Windows Internals、パート1(第6版)(開発者向けリファレンス)で詳しく説明されています。
PeekMessage
。そのため、Windowsがアプリケーションにメッセージを送信し、5秒以内に信号が送られない場合、アプリケーションが応答していないとマークします。実際、最近のWindowsでは、ウィンドウはユーザー入力に時間内に応答しなかった場合にのみ「応答なし」とマークされます。キーまたは何かをクリックするか押すまで、アプリケーションは応答しない「表示」なしで数分。
実際、Windowsはアプリケーションが応答していないことを常に認識しているわけではありません。アプリケーションは、ウィンドウを備えた対話型アプリケーションである必要があり、ウィンドウは、アプリケーションが応答していないとWindowsが判断する前に、アプリケーションが処理に失敗したというメッセージを受信する必要があります。
たとえば、Windowsには、コマンドラインから実行されるユーザーインターフェイスを持たない数値演算アプリケーションが機能しているのか、無限ループに陥っているのかを知る方法がありません。
Windowsの対話型グラフィカルアプリケーションは、メッセージキューを継続的にポーリングすることによりイベントを受信します。Windowsは、このメッセージキューにキーボード、マウス、タイマーなどのイベントを追加します。アプリケーションがメッセージキューのポーリングにしばらく失敗した場合(IsHungAppWindow()関数のドキュメントに記載されているタイムアウトは5秒です)、Windowsはアプリケーションを「ハング」したと見なします。 (応答なし)」またはローカライズ版の同等のテキスト)、ユーザーがウィンドウを操作しようとするとウィンドウのコンテンツがグレー表示されます。
Windowsが認識しない方法でアプリケーションがハングする可能性があります。たとえば、アプリケーションはメッセージキュー内のメッセージを適切に処理せずにポーリングし続けることがあるため、すべての実用的な意図と目的に対して、Windowsが応答しないことを認識せずに「ハング」しているように見えます。
Windowsはオペレーティングシステムであり、実行中のすべてのプログラムを監視します。
Windowsは、イベントを使用してウィンドウベースのアプリケーションと通信します。すべてのプログラムには、着信イベントを常にリッスンして処理するスレッドがあります。たとえば、ボタンまたは通知領域のアイコンをクリックすると、Windowsはイベントを生成し、適切なプロセスにフィードします。その後、プロセスはその処理方法を決定できます。
Windowsでは、プログラムとのやり取りはすべてイベントベースです。したがって、プログラムが受信イベントを長時間処理しない場合、応答しません。@DavidPostillが彼の答えで見つけて指摘したように、タイムアウトは5秒です。PeekMessage
イベントキューからイベントを取得する関数です。
あなたの質問に対する答えはイエス/ノーです。
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つにすぎません。