Skąd Windows wie, czy program nie odpowiada?


174

Skąd Windows wie, czy program nie odpowiada? Czy stale odpytuje wszystkie uruchomione aplikacje?



@ magicandre1981 Ta strona proponuje jeden sposób sprawdzenia, czy program aktywnie coś robi, ale nie jest to sposób, w jaki system Windows faktycznie korzysta.
Kevin Panko,

Spójrz na kolejkę komunikatów Windows, kandydatem jest funkcja PeekMessage ()
Luciano

Odpowiedzi:


150

Aplikacja pobiera zdarzenia z kolejki udostępnianej przez system Windows.

Jeśli aplikacja nie odpytuje kolejki zdarzeń przez jakiś czas (5 sekund), na przykład podczas wykonywania długich obliczeń, wówczas Windows zakłada, że ​​aplikacja została zawieszona i ostrzega użytkownika.

Aby tego uniknąć, aplikacje powinny przesyłać kosztowne obliczenia do wątków roboczych lub dzielić przetwarzanie i upewnić się, że kolejka jest regularnie sprawdzana.


27
↑ To. Nie ma nic wspólnego z planowaniem lub jak sugeruje w przyjętej odpowiedzi, tylko czy regularnie dzwonisz GetMessage(lub tym podobne) i DispatchMessage.
Damon

1
Przyjęta odpowiedź, odnosząc się do IsHungAppWindowpoprawnych uwag, stwierdza, że ​​program w fazie uruchamiania nie musi wywoływać GetMessage.
MSalters,

@MSalters Z uruchomieniem definiuje się czas przed pierwszym GetMessage? Ta funkcja umożliwia działanie prostych aplikacji wiersza polecenia bez konieczności zawieszania się, ponieważ nie trzeba sondować kolejki.
maniak zapadkowy

4
@ratchetfreak: Prawdopodobnie przed pierwszym wywołaniem CreateWindow. Aplikacje wiersza poleceń to różne bestie; działają w ConHost.EXE i współpracuje z nimi z systemem Windows GUI.
MSalters

1
wydaje mi się również, że w Windows 7 (i być może wcześniej) Windows zauważy to znacznie wcześniej, jeśli spróbujesz w jakiś sposób manipulować oknem. na przykład, jeśli program nie przetwarza wiadomości zmaksymalizowania lub przeniesienia, Windows 7 przeskoczy w prawo do braku odpowiedzi po około 1 lub 2 sekundach.
Dave Cousineau

78

Skąd Windows wie, czy program nie odpowiada?

Bez kodu źródłowego dla systemu Windows nie jesteśmy pewni, co robi wewnętrznie.

Istnieje funkcja Windows SDK, IsHungAppWindowktórej można użyć.

Uznaje się, że aplikacja nie odpowiada, jeśli nie czeka na dane wejściowe, nie jest przetwarzana podczas uruchamiania i nie wywołała PeekMessage w wewnętrznym limicie czasu wynoszącym 5 sekund.

Źródło IsHungAppWindow

Jeśli okno najwyższego poziomu przestanie odpowiadać na wiadomości na dłużej niż kilka sekund, system uzna, że ​​okno nie odpowiada. W takim przypadku system ukrywa okno i zamienia je na okno-widmo, które ma tę samą kolejność Z, lokalizację, rozmiar i atrybuty wizualne. Dzięki temu użytkownik może go przenieść, zmienić rozmiar, a nawet zamknąć aplikację. Są to jednak jedyne dostępne działania, ponieważ aplikacja w rzeczywistości nie odpowiada.

Źródło o wiadomościach i kolejkach wiadomości


Czy stale odpytuje wszystkie uruchomione aplikacje?

Nie. Aplikacje nie są odpytywane, ale mają określony czas procesora.

Windows ma system planowania, który daje procesorowi czas na wątki aplikacji.

Algorytm planowania jest złożony i jest w pełni opisany w Windows Wewnętrznych, Część 1 (wydanie 6) (Developer Reference) .


2
Stan zawieszenia nie jest oparty na procesorze. Większość programów jest „zawieszonych” w tym sensie przez 99,999% czasu i nic nie robi.
usr

2
@usr Gdzie powiedziałem, że „zawieszony” zależy od procesora?
DavidPostill

2
@usr Pierwsza połowa odpowiedzi brzmi: „Czy ciągle odpytuje wszystkie uruchomione aplikacje?”. Druga połowa odpowiada „Skąd Windows wie, czy program nie odpowiada?” OP zadał dwa pytania w jednym;)
DavidPostill

9
Ale to tak naprawdę nie jest odpytywanie, prawda? Zakładam, że wewnętrzne są bardziej jak uchwyt oczekiwania na oknie jest sygnalizowany, kiedy zadzwonisz PeekMessage. Tak więc, gdy system Windows wysyła komunikat do aplikacji i nie otrzymuje sygnału w ciągu pięciu sekund, oznacza to, że aplikacja nie odpowiada. W rzeczywistości w nowszym systemie Windows okno jest oznaczone jako „nie odpowiada” tylko wtedy, gdy nie zareaguje na dane wprowadzone przez użytkownika w odpowiednim czasie - dopóki nie spróbuję kliknąć lub nacisnąć klawisza lub czegoś innego, aplikacja może z łatwością „zawiesić się” minut bez „pojawienia się” braku odpowiedzi.
Luaan,

2
Możesz usunąć wszystko powyżej „Informacje o wiadomościach i kolejkach wiadomości”, ponieważ nie pomaga to w udzieleniu odpowiedzi. System Windows wie, że aplikacja przestała odpowiadać, ponieważ przestaje pompować wiadomości. Aplikacja może jednak działać, ponieważ robi coś intensywnego zamiast pompować wiadomości (ale jest to źle zaprojektowany program).
Andy,

32

W rzeczywistości system Windows nie zawsze wie, że aplikacja nie odpowiada. Aplikacja musi być aplikacją interaktywną z oknem, a okno musi odbierać komunikaty, których aplikacja nie przetwarza, zanim system Windows stwierdzi, że aplikacja nie odpowiada.

Na przykład system Windows nie ma sposobu, aby dowiedzieć się, czy aplikacja powodująca awarie liczb bez interfejsu użytkownika uruchamianego z wiersza poleceń działa, czy może utknęła w nieskończonej pętli.

Interaktywne aplikacje graficzne w systemie Windows odbierają zdarzenia poprzez ciągłe przeszukiwanie kolejki komunikatów. System Windows zapełnia tę kolejkę komunikatów zdarzeniami dotyczącymi klawiatury, myszy, timera itp. Jeśli aplikacja nie przeszukuje kolejki komunikatów przez pewien czas (5 sekund to limit czasu wymieniony w dokumentacji funkcji IsHungAppWindow ()), system Windows uznaje aplikację za „zawieszoną”, co może wskazywać, zmieniając tytuł okna (dodając tekst „ (Nie odpowiada) ”lub równoważny tekst w zlokalizowanych wersjach) i wyszarzenie zawartości okna, jeśli użytkownik spróbuje wejść w interakcję z oknem.

Aplikacje mogą się zawieszać w sposób, którego system Windows nie rozpoznaje. Na przykład aplikacja może kontynuować odpytywanie o wiadomości w swojej kolejce komunikatów bez odpowiedniego działania na nich, więc dla wszystkich praktycznych intencji i celów wydaje się „zawieszona” bez rozpoznania przez Windows, że nie odpowiada.


8
Brak odpowiedzi z definicji oznacza nieprzetwarzanie komunikatów okna, więc nie dotyczy usług ani aplikacji konsolowych, więc powiedziałbym, że Windows zawsze wie, czy aplikacja nie odpowiada. Mylisz martwe zamki i nie reagujesz.
Andy,

Oczywiście może wiedzieć, czy program nie odpowiada. „Brak odpowiedzi” to nie to samo, co „utknięcie w nieskończonej pętli”
BlueRaja - Danny Pflughoeft

1
W rzeczywistości aplikacja może pobierać wiadomości za pośrednictwem GetMessage () i nie przetwarzać ich, a system Windows nie rozpoznałby jej jako „nie reagującej”, mimo że z pewnością nie odpowiadałby jej użytkownikowi. Termin „nie odpowiada” jest również często używany do opisania aplikacji sieciowych, usługowych, interaktywnego wiersza poleceń itp.; AFAIK nie ma formalnej definicji, która ogranicza wyrażenie do aplikacji okienkowych. Zarówno zakleszczenie, jak i nieskończona pętla (lub jakikolwiek inny błąd programowania) mogą spowodować, że aplikacja przestanie odpowiadać, ale nie, nie pomyliłem przyczyny i skutku.
Viktor Toth,

10

Windows to system operacyjny, który nadzoruje wszystkie uruchomione programy.

System Windows komunikuje się z aplikacjami opartymi na systemie Windows za pomocą zdarzeń. Każdy program ma wątek, który stale nasłuchuje nadchodzących zdarzeń i przetwarza je. Na przykład po kliknięciu przycisku lub ikony obszaru powiadomień system Windows generuje zdarzenie i przekazuje je do odpowiedniego procesu. Proces może następnie zdecydować, jak sobie z tym poradzić.

Wszystkie interakcje z programami są oparte na zdarzeniach w systemie Windows, więc jeśli program nie przetwarza przychodzących zdarzeń zbyt długo, oznacza to, że nie odpowiada. Jak @DavidPostill znalazł i zauważył w swojej odpowiedzi , limit czasu wynosi 5 sekund. PeekMessageto funkcja, która pobiera zdarzenie z kolejki zdarzeń.


0

Odpowiedź na twoje pytanie brzmi: tak / nie.

Podczas gdy system operacyjny Windows może i odpytuje aplikacje ze zdarzeniami w kolejce Windows Messaging, programy mają absolutnie zerowy obowiązek łączenia się z WinAPI lub obsługi / odbierania kolejki Windows. Nawet odpowiedź na wiadomość w kolejce nie informuje systemu Windows, czy program „zablokował się”, czy nie. To wskaźnik, ale to wszystko. Prawdziwa odpowiedź jest nieco bardziej skomplikowana.

Prawdziwa odpowiedź

Ludzie żywią się tutaj wokół właściwej odpowiedzi. Określenie, czy program „nie odpowiada” jest odmianą „ problemu zatrzymania ”, który formalnie jest nierozstrzygalny w informatyce. Krótkie wyjaśnienie jest takie, że procesor nie może działać jako strona trzecia obserwująca się w celu ustalenia, czy podprogram utknął w nieskończonej pętli, nie robiąc nic, a nie zwiększając licznik, który zakończy się na pewnej stałej, normalnej liczbie. Oba z nich można uznać za ściśle zamknięte pętle. Jeden się zatrzymuje, drugi nigdy się nie skończy. Nawet ty, jako osoba, nie wiesz, czy program faktycznie odpowiada, czy nie, szczególnie jeśli jest w ściśle zamkniętej pętli - wiesz tylko, jeśli uważasz, że powinien (odpowiedzieć).

Z punktu widzenia systemu Windows obie te pętle „nie odpowiadają” . Właśnie dlatego system Windows daje możliwość czekania lub zakończenia, ponieważ nie jest w stanie tego stwierdzić.

Więc następstwem jest „Dlaczego okna wiedzieć, że proces jest reagować?” Odpowiedź jest raczej sprytna. Gdy proces jest kompilowany w wielowątkowym i wieloprocesowym systemie operacyjnym, czasem nawet w ciasno zamkniętych pętlach, kompilator może dodać komendę fed () , która zapewnia wygodne powiadomienie procesora, że ​​może przełączyć się na inne uruchomione procesy . To „rezygnuje” procesor i „przełączanie kontekstu” (jak to się nazywa) zdarza się, że pozwala na OS (Windows w zestawie), aby odpowiedzieć na inne wydarzenia w stos, z których niektóre zawierają śledzenie, że proces nie odpowiedział.

** Nie oznacza to, że proces odpowiadania zostanie zakończony . ** Proces wewnątrz nieskończonej pętli może dać procesorowi, umożliwiając systemowi Windows przetwarzanie innych zdarzeń.

W niektórych programach systemu Windows program będzie obsługiwał sygnały systemu operacyjnego Windows, co może powiedzieć systemowi, że „odpowiada”, ale żaden program nie jest do tego zobowiązany. Możesz pisać dość proste blokowanie procesora, nie kończące się programy, nawet w językach wyższego poziomu w systemie Windows, takich jak perl, php, python, a Windows może nie wykryć, że nie kończy i nie odpowiada. W tym momencie system Windows zależy od heurystyki - obciążenia procesora, pamięci, liczby przerwań obsługiwanych przez procesor podczas działania programu w celu „odgadnięcia”. Ponownie, w tym momencie Windows musi poprosić cię o zakończenie, ponieważ tak naprawdę nie wie, czy powinien.

Zobacz także (poprawną) odpowiedź Viktora. Zignoruj ​​komentarze dotyczące tego, czy „brak odpowiedzi” nie jest tym samym, co nieskończona pętla. Istnieją różne rodzaje komunikatów, przerwań, pętli, które aplikacja może obsługiwać lub nie, bez informowania kolejki komunikatów systemu Windows. Obsługa kolejki komunikatów jest tylko jednym z wielu rodzajów zdarzeń, na które system operacyjny liczy, próbując zgadnąć, czy proces się zawiesił.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.