Woher weiß Windows, ob ein Programm nicht reagiert?


174

Woher weiß Windows, ob ein Programm nicht reagiert? Werden ständig alle laufenden Anwendungen abgefragt?



@ magicandre1981 Auf dieser Seite können Sie überprüfen, ob ein Programm gerade etwas ausführt, aber Windows verwendet dies nicht.
Kevin Panko

Schauen Sie sich die Windows-Nachrichtenwarteschlange an, ein Kandidat ist die PeekMessage () -Funktion
Luciano

Antworten:


150

Eine Anwendung ruft die Ereignisse aus einer von Windows bereitgestellten Warteschlange ab.

Wenn die Anwendung die Ereigniswarteschlange für eine Weile (5 Sekunden) nicht abruft, z. B. bei einer langen Berechnung, geht Windows davon aus, dass die Anwendung hängen bleibt, und benachrichtigt den Benutzer.

Um zu vermeiden, dass Anwendungen teure Berechnungen an Worker-Threads senden oder die Verarbeitung aufteilen, sollten Sie sicherstellen, dass die Warteschlange regelmäßig abgefragt wird.


27
↑ Dies. Es hat nichts mit Zeitplanung oder GetMessageÄhnlichem zu tun, wie in der angenommenen Antwort vorgeschlagen, sondern nur, ob Sie regelmäßig anrufen (oder dergleichen) und DispatchMessage.
Damon

1
In der akzeptierten Antwort wird unter IsHungAppWindowkorrekter Bezugnahme darauf hingewiesen, dass ein Programm in der Startphase nicht aufgerufen werden muss GetMessage.
MSalters

@MSalters Wird der Start als die Zeit vor dem ersten definiert GetMessage? Mit dieser Funktion können einfache Befehlszeilenanwendungen verwendet werden, ohne als hängen zu gelten, da sie die Warteschlange nicht abrufen müssen.
Ratschenfreak

4
@ratchetfreak: Vermutlich vor dem ersten CreateWindow-Aufruf. Kommandozeilen-Apps sind verschiedene Biester. Sie laufen in ConHost.EXE und es interagiert mit dem Windows-GUI-System für sie.
MSalters

1
Außerdem scheint es mir, dass Windows 7 (und möglicherweise früher) dies viel früher bemerken wird, wenn Sie versuchen, das Fenster auf irgendeine Weise nicht zu manipulieren. Wenn ein Programm keine Maximierungs- oder Verschiebungsmeldung verarbeitet, reagiert Windows 7 nach etwa 1 oder 2 Sekunden nicht mehr.
Dave Cousineau

78

Woher weiß Windows, ob ein Programm nicht reagiert?

Ohne den Quellcode für Windows können wir nicht sicher sein, was es intern tut.

Es gibt eine SDK-Windows-Funktion IsHungAppWindow, die verwendet werden kann.

Eine Anwendung reagiert nicht, wenn sie nicht auf Eingaben wartet, sich nicht in der Startverarbeitung befindet und PeekMessage nicht innerhalb des internen Zeitlimits von 5 Sekunden aufgerufen hat .

Source IsHungAppWindow-Funktion

Wenn ein Fenster der obersten Ebene länger als einige Sekunden nicht mehr auf Nachrichten reagiert, geht das System davon aus, dass das Fenster nicht reagiert. In diesem Fall blendet das System das Fenster aus und ersetzt es durch ein Geisterfenster mit derselben Z-Reihenfolge, Position, Größe und denselben visuellen Attributen. Auf diese Weise kann der Benutzer die Anwendung verschieben, ihre Größe ändern oder sie sogar schließen. Dies sind jedoch die einzigen verfügbaren Aktionen, da die Anwendung tatsächlich nicht reagiert.

Quelle zu Nachrichten und Nachrichtenwarteschlangen


Werden ständig alle laufenden Anwendungen abgefragt?

Nein. Anwendungen werden nicht abgefragt, erhalten aber Prozessorzeit.

Windows verfügt über ein Planungssystem, das Anwendungsthreads Prozessorzeit gibt.

Der Planungsalgorithmus ist komplex und wird ausführlich in Windows Internals, Teil 1 (6. Ausgabe) (Entwicklerreferenz) beschrieben .


2
Der Hang-Status basiert nicht auf der CPU. Die meisten Programme "hängen" in diesem Sinne 99,999% der Zeit und tun nichts.
usr

2
@usr Wo habe ich gesagt, dass "hing" von der CPU abhängt?
DavidPostill

2
@usr Die erste Hälfte der Antwort lautet "Werden ständig alle laufenden Anwendungen abgefragt?". Die zweite Hälfte antwortet auf "Woher weiß Windows, ob ein Programm nicht reagiert?". Das OP stellte zwei Fragen in einer;)
DavidPostill

9
Es ist aber nicht wirklich eine Umfrage, oder? Ich nehme an, die Interna werden eher als Wartehandle am Fenster signalisiert, wenn Sie anrufen PeekMessage. Wenn also Windows eine Nachricht an die Anwendung sendet und diese nicht innerhalb von fünf Sekunden signalisiert wird, wird die Anwendung als nicht reagierend markiert. Tatsächlich wird das Fenster unter neueren Windows nur dann als "nicht reagierend" markiert, wenn es nicht rechtzeitig auf Benutzereingaben reagiert - bis ich versuche, auf eine Taste oder etwas zu klicken oder zu drücken, kann die Anwendung leicht "dranbleiben" Minuten ohne "erscheinen" nicht ansprechbar.
Luaan

2
Sie können alles über "Über Nachrichten und Nachrichtenwarteschlangen" löschen, da dies für die Antwort nicht hilfreich ist. Windows weiß, dass eine App nicht mehr reagiert, weil keine Nachrichten mehr gesendet werden. Die App könnte zwar ausgeführt werden, da sie etwas Intensives tut, anstatt Nachrichten zu pumpen (aber das ist ein schlecht gestaltetes Programm).
Andy

32

Tatsächlich weiß Windows nicht immer, dass eine Anwendung nicht reagiert. Die Anwendung muss eine interaktive Anwendung mit einem Fenster sein und das Fenster muss Nachrichten empfangen, die die Anwendung nicht verarbeiten kann, bevor Windows zu dem Schluss kommt, dass die Anwendung nicht reagiert.

Beispielsweise kann Windows nicht erkennen, ob eine Anwendung zur Zahleneingabe ohne Benutzeroberfläche, die über die Befehlszeile ausgeführt wird, ihre Aufgabe erfüllt oder möglicherweise in einer Endlosschleife steckt.

Interaktive Grafikanwendungen in Windows empfangen Ereignisse, indem sie kontinuierlich eine Nachrichtenwarteschlange abrufen. Windows füllt diese Nachrichtenwarteschlange mit Tastatur-, Maus-, Timer- usw. Ereignissen. Wenn eine Anwendung die Nachrichtenwarteschlange einige Zeit lang nicht abruft (5 Sekunden ist das in der IsHungAppWindow () - Funktionsdokumentation erwähnte Zeitlimit), betrachtet Windows die Anwendung als "hängen geblieben", was durch Ändern des Fenstertitels (Hinzufügen des Texts) angezeigt werden kann. (Reagiert nicht) "oder äquivalenter Text in lokalisierten Versionen) und das Ausblenden des Fensterinhalts, wenn der Benutzer versucht, mit dem Fenster zu interagieren.

Anwendungen können auf eine Weise hängen, die Windows nicht erkennt. Beispielsweise kann eine Anwendung weiterhin Nachrichten in ihrer Nachrichtenwarteschlange abrufen, ohne ordnungsgemäß darauf zu reagieren, sodass sie praktisch "hängen" scheint, ohne dass Windows erkennt, dass sie nicht reagiert.


8
Per definitionem nicht zu antworten bedeutet, Fenstermeldungen nicht zu verarbeiten. Daher gilt dies nicht für Dienste oder Konsolen-Apps. Daher würde ich sagen, dass Windows immer weiß, ob eine App nicht reagiert. Sie verwechseln Dead Locks und reagieren nicht.
Andy

Natürlich kann es wissen, ob ein Programm nicht reagiert. "Nicht antworten" ist nicht dasselbe wie "in einer Endlosschleife stecken"
BlueRaja - Danny Pflughoeft

1
Tatsächlich kann eine Anwendung Nachrichten über GetMessage () abrufen und nicht verarbeiten, und sie wird von Windows nicht als "nicht antwortend" erkannt, obwohl sie dem Benutzer mit Sicherheit nicht zu antworten scheint. Der Begriff "nicht antwortend" wird auch häufig verwendet, um Netzwerk-, Dienst-, interaktive Befehlszeilenanwendungen usw. zu beschreiben. AFAIK: Es gibt keine formale Definition, die den Ausdruck auf Anwendungen mit Fenstern beschränkt. Sowohl ein Deadlock als auch eine Endlosschleife (oder ein anderer Programmierfehler) können dazu führen, dass eine Anwendung nicht mehr reagiert. Ich habe Ursache und Wirkung jedoch nicht verwechselt.
Viktor Toth

10

Windows ist ein Betriebssystem, das alle laufenden Programme überwacht.

Windows kommuniziert mit fensterbasierten Anwendungen über Ereignisse. Jedes Programm hat einen Thread, der ständig auf eingehende Ereignisse wartet und diese verarbeitet. Wenn Sie beispielsweise auf eine Schaltfläche oder ein Benachrichtigungsbereichssymbol klicken, generiert Windows ein Ereignis und leitet es in den entsprechenden Prozess ein. Der Prozess kann dann entscheiden, wie er damit umgeht.

Alle Interaktionen mit Programmen sind in Windows ereignisbasiert. Wenn das Programm eingehende Ereignisse nicht zu lange verarbeitet, bedeutet dies, dass es nicht reagiert. Wie @DavidPostill in seiner Antwort festgestellt und notiert hat , beträgt die Zeitüberschreitung 5 Sekunden. PeekMessageist die Funktion, die ein Ereignis aus der Ereigniswarteschlange abruft.


0

Die Antwort auf Ihre Frage lautet Ja / Nein.

Während das Windows-Betriebssystem Anwendungen mit Ereignissen in der Windows-Messaging-Warteschlange abrufen kann und ausführt, besteht für Programme keine Verpflichtung, eine Verbindung zur WinAPI herzustellen oder die Windows-Warteschlange zu bearbeiten bzw. zu beantworten. Selbst das Beantworten einer Nachricht in der Warteschlange sagt Windows nicht, ob das Programm "abgestürzt" ist oder nicht. Es ist ein Indikator, aber das ist alles. Die eigentliche Antwort ist etwas komplizierter.

Die wahre Antwort

Die Leute machen sich hier Gedanken über die eigentliche Antwort. Die Feststellung, ob ein Programm "nicht reagiert", ist eine Variante des " Halteproblems ", das in der Informatik formal nicht zu entscheiden ist. Die kurze Erklärung ist, dass der Prozessor nicht als ein Dritter agieren kann, der sich selbst beobachtet, um zu bestimmen, ob eine Subroutine in einer Endlosschleife steckt, und nichts dagegen tut, einen Zähler zu erhöhen, der bei einer festen, normalen Zahl endet. Beide können als eng geschlossene Schleifen betrachtet werden. Einer hält an, der andere wird niemals enden. Sogar Sie als Person wissen nicht, ob ein Programm tatsächlich reagiert oder nicht, insbesondere wenn es sich in einem engen Regelkreis befindet - Sie wissen nur, wenn Sie der Meinung sind, dass es reagieren sollte.

Aus Windows-Sicht reagieren beide Schleifen nicht . Aus diesem Grund haben Sie in Windows die Wahl, zu warten oder zu beenden, da dies nicht festgestellt werden kann.

So ist die logische Folge ist „warum Fenster wissen , dass ein Prozess ist , reagiert?“ Die Antwort ist ziemlich schlau. Wenn ein Prozess in einem Multi-Thread- und Multi-Prozess-Betriebssystem kompiliert wird, manchmal sogar in eng geschlossenen Schleifen, fügt der Compiler möglicherweise einen yield () -Befehl hinzu, der dem Prozessor eine bequeme Benachrichtigung gibt, dass er zu anderen laufenden Prozessen wechseln kann . Es „gibt auf“ der Prozessor und einen „Kontextwechsel“ (wie sie genannt wird) kommt vor, dass ermöglicht das Betriebssystem (Windows enthalten) andere Ereignisse in dem Stapel zu beantworten, von denen einige auch Tracking , dass der Prozess hat reagiert.

** Dies bedeutet nicht, dass ein antwortender Prozess beendet wird . ** Ein Prozess innerhalb einer Endlosschleife kann den Prozessor ergeben, sodass Windows andere Ereignisse verarbeiten kann.

In einigen Windows-Programmen verarbeitet das Programm Windows-Betriebssystemsignale, die dem Betriebssystem mitteilen, dass es "reagiert", aber kein Programm ist dazu verpflichtet. Sie können ganz einfache Programme schreiben, die die CPU überlasten und nicht terminieren, selbst in höheren Windows-Sprachen wie Perl, PHP, Python und Windows, die möglicherweise nicht erkennen, dass sie nicht terminieren und nicht reagieren. Zu diesem Zeitpunkt hängt Windows von den Heuristiken ab - CPU-Auslastung, Arbeitsspeicher, wie viele Interrupts der Prozessor verarbeitet hat, während das Programm ausgeführt wurde, um "zu raten". An diesem Punkt muss Windows Sie erneut zum Beenden auffordern, da es wirklich nicht weiß, ob dies der Fall sein sollte.

Siehe auch die (richtige) Antwort von Viktor. Ignorieren Sie die Kommentare dazu, ob "Nicht antworten" nicht mit einer Endlosschleife identisch ist. Es gibt alle Arten von Nachrichten, Interrupts und Schleifen, die eine Anwendung möglicherweise verarbeiten kann oder nicht, ohne die Windows-Nachrichtenwarteschlange zu informieren. Die Behandlung der Nachrichtenwarteschlange ist nur eines von vielen Ereignissen, bei denen das Betriebssystem versucht, zu erraten, ob ein Prozess hängt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.