172

Как Windows узнает, что программа не отвечает? Постоянно опрашивает все запущенные приложения?

5 ответов5

149

Приложение получает события из очереди, предоставленной Windows.

Если приложение не опрашивает очередь событий некоторое время (5 секунд), например, при выполнении длинных вычислений, то Windows предполагает, что приложение зависло, и предупреждает пользователя.

Чтобы избежать этого, приложения должны передавать дорогостоящие вычисления рабочим потокам или разделять обработку и обеспечивать регулярный опрос очереди.

78

Как Windows узнает, что программа не отвечает?

Без исходного кода для Windows мы не можем быть уверены, что он делает внутри.

Существует функция Windows SDK IsHungAppWindow которую можно использовать.

Считается, что приложение не отвечает, если оно не ожидает ввода, не находится в процессе запуска и не вызвало PeekMessage в течение внутреннего периода ожидания 5 секунд.

Исходная функция IsHungAppWindow

Если окно верхнего уровня перестает отвечать на сообщения более чем на несколько секунд, система считает, что окно не отвечает. В этом случае система скрывает окно и заменяет его призрачным окном, имеющим тот же Z-порядок, местоположение, размер и визуальные атрибуты. Это позволяет пользователю перемещать его, изменять его размер или даже закрывать приложение. Однако это единственные доступные действия, потому что приложение на самом деле не отвечает.

Источник О сообщениях и очередях сообщений


Постоянно опрашивает все запущенные приложения?

Нет. Приложения не опрашиваются, но получают время процессора.

В Windows есть система планирования, которая дает процессору время для потоков приложений.

Алгоритм планирования является сложным и полностью описан в Windows Internals, часть 1 (6-е издание) (Справочник разработчика).

32

На самом деле, Windows не всегда знает, что приложение не отвечает. Приложение должно быть интерактивным приложением с окном, и окно должно получать сообщения, которые приложение не может обработать, прежде чем Windows решит, что приложение не отвечает.

Например, в Windows нет способа узнать, выполняет ли какое-либо приложение, работающее с числами, без пользовательского интерфейса, запускаемого из командной строки, или, возможно, застрявший в бесконечном цикле.

Интерактивные графические приложения в Windows получают события, непрерывно опрашивая очередь сообщений. Windows заполняет эту очередь сообщений событиями клавиатуры, мыши, таймера и т.д. Если приложению не удается опросить очередь сообщений в течение некоторого времени (5 секунд - это время ожидания, указанное в документации по функции IsHungAppWindow ()), Windows считает приложение "зависшим", что можно указать, изменив заголовок окна (добавив текст). (Не отвечает) "или эквивалентный текст в локализованных версиях) и выделение содержимого окна, если пользователь пытается взаимодействовать с окном.

Приложения могут зависать так, что Windows их не распознает. Например, приложение может продолжить опрос сообщений в своей очереди сообщений, не воздействуя должным образом на них, поэтому для всех практических целей и задач оно будет казаться "зависшим" без признания Windows, что оно не отвечает.

10

Windows - операционная система, она контролирует все запущенные программы.

Windows связывается с оконными приложениями, используя события. Каждая программа имеет поток, который постоянно прослушивает входящие события и обрабатывает их. Например, когда вы нажимаете кнопку или значок области уведомлений, Windows генерирует событие и передает его в соответствующий процесс. Затем процесс может решить, как с этим справиться.

Все взаимодействия с программами основаны на событиях в Windows, поэтому, когда программа не обрабатывает входящие события слишком долго, это означает, что она не отвечает. Как @DavidPostill нашел и отметил в своем ответе, время ожидания составляет 5 секунд. PeekMessage - это функция, которая получает событие из очереди событий.

0

Ответ на ваш вопрос - да / нет.

В то время как операционная система Windows может опрашивать и обрабатывать приложения с событиями в очереди сообщений Windows, программы абсолютно не обязаны связываться с WinAPI или обрабатывать / отвечать на очередь Windows. Даже ответ на сообщение в очереди не говорит Windows, была ли программа "заблокирована" или нет. Это показатель, но это все, что есть. Реальный ответ немного сложнее.

Настоящий ответ

Люди обдумывают фактический ответ здесь. Определение того, "не отвечает" ли программа, является вариантом « проблемы остановки », которая формально неразрешима в компьютерной науке. Краткое объяснение состоит в том, что процессор не может выступать в роли третьей стороны, наблюдающей за собой, чтобы определить, застряла ли подпрограмма в бесконечном цикле, ничего не делая против увеличения счетчика, который завершится на некотором фиксированном нормальном числе. Оба из них можно считать плотно замкнутыми петлями. Один останавливается, другой никогда не закончится. Даже вы, как человек, не знаете, отвечает ли программа на самом деле или нет, особенно если она находится в плотно замкнутом цикле - вы знаете только, если считаете, что она должна (отвечать).

С точки зрения Windows, оба этих цикла "не отвечают". Вот почему Windows дает вам выбор ждать или прекратить, потому что он не может сказать.

Таким образом, следствие является «почему окна знают , что процесс отвечает?«Ответ довольно умный. Когда процесс компилируется в многопоточной и многопроцессорной ОС, иногда даже в сильно замкнутых циклах, компилятор может добавить команду yield() , которая предоставляет удобное уведомление процессору о том, что он может переключиться на другие запущенные процессы , Это "отдает" процессор и "переключение контекста" (как его называют) бывает , что позволяет ОС (Windows включен) , чтобы ответить на другие события в стеке, некоторые из которых включают в себя отслеживание , что процесс ответил.

** Это не означает, что процесс ответа будет прекращен. ** Процесс внутри бесконечного цикла может дать процессор, позволяющий Windows обрабатывать другие события.

В некоторых программах Windows программа обрабатывает сигналы ОС Windows, которые могут сообщить ОС, что она "отвечает", но ни одна программа не обязана это делать. Вы можете написать довольно простую загрузку процессора, программы без прерывания даже на языках более высокого уровня в Windows, таких как perl, php, python и Windows, которые могут не обнаружить, что он не завершает работу и не отвечает. В этот момент Windows зависит от эвристики - загрузки процессора, памяти, сколько прерываний обработал процессор, пока программа работала, чтобы "угадать". Опять же, в этот момент Windows должна попросить вас прекратить работу, потому что она действительно не знает, должна ли она.

Смотрите также ответ Виктора (правильный). Не обращайте внимания на комментарии о том, не "не отвечает" не то же самое, что бесконечный цикл. Существуют всевозможные сообщения, прерывания, циклы, которые приложение может обрабатывать или не обрабатывать, не сообщая об очереди сообщений Windows. Обработка очереди сообщений - это только один из многих видов событий, на которые ОС ведет счетчики, пытаясь угадать , завис ли процесс.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .