Как Windows узнает, что программа не отвечает? Постоянно опрашивает все запущенные приложения?
Как Windows узнает, что программа не отвечает? Постоянно опрашивает все запущенные приложения?
Ответы:
Приложение получает события из очереди, предоставленной Windows.
Если приложение не опрашивает очередь событий некоторое время (5 секунд), например, при выполнении длинных вычислений, то Windows предполагает, что приложение зависло, и предупреждает пользователя.
Чтобы избежать этого, приложения должны передавать дорогостоящие вычисления рабочим потокам или разделять обработку и обеспечивать регулярный опрос очереди.
GetMessage
(или тому подобное) и DispatchMessage
.
IsHungAppWindow
правильно отмечаемым, что программе на этапе запуска не нужно вызывать GetMessage
.
GetMessage
? Эта функция позволяет простым приложениям командной строки работать без зависания, поскольку им не нужно опрашивать очередь.
Без исходного кода для Windows мы не можем быть уверены, что он делает внутри.
Существует функция Windows SDK, IsHungAppWindow
которую можно использовать.
Считается, что приложение не отвечает, если оно не ожидает ввода, не находится в процессе запуска и не вызвало PeekMessage в течение внутреннего тайм-аута в 5 секунд.
Исходная функция IsHungAppWindow
Если окно верхнего уровня перестает отвечать на сообщения более чем на несколько секунд, система считает, что окно не отвечает. В этом случае система скрывает окно и заменяет его призрачным окном, имеющим тот же Z-порядок, местоположение, размер и визуальные атрибуты. Это позволяет пользователю перемещать его, изменять его размер или даже закрывать приложение. Однако это единственные доступные действия, потому что приложение на самом деле не отвечает.
Источник О сообщениях и очередях сообщений
Нет. Приложения не опрашиваются, но получают время процессора.
В Windows есть система планирования, которая дает процессору время для потоков приложений.
Алгоритм планирования является сложным и полностью описан в Windows Internals, часть 1 (6-е издание) (Справочник разработчика) .
PeekMessage
. Поэтому, когда Windows отправляет сообщение приложению и не получает сигнал в течение пяти секунд, оно помечает приложение как не отвечающее. И на самом деле, в более поздних версиях Windows окно помечается как «не отвечающее» только в том случае, если оно не отвечает вовремя на ввод пользователя - пока я не попытаюсь щелкнуть или нажать клавишу или что-то еще, приложение может легко оставаться «зависшим» для минут без «появления» неотвечающих.
На самом деле, Windows не всегда знает, что приложение не отвечает. Приложение должно быть интерактивным приложением с окном, и окно должно получать сообщения, которые приложение не может обработать, прежде чем Windows решит, что приложение не отвечает.
Например, у Windows нет возможности узнать, выполняет ли свое дело приложение, работающее с числами без пользовательского интерфейса, запускаемого из командной строки, или, возможно, застряло в бесконечном цикле.
Интерактивные графические приложения в Windows получают события, непрерывно опрашивая очередь сообщений. Windows заполняет эту очередь сообщений событиями клавиатуры, мыши, таймера и т. Д. Если приложению не удается опросить очередь сообщений в течение некоторого времени (5 секунд - это время ожидания, указанное в документации по функции IsHungAppWindow ()), Windows считает приложение «зависшим», что можно указать, изменив заголовок окна (добавив текст). (Не отвечает) "или эквивалентный текст в локализованных версиях) и выделение содержимого окна, если пользователь пытается взаимодействовать с окном.
Приложения могут зависать так, что Windows их не распознает. Например, приложение может продолжить опрос сообщений в своей очереди сообщений, не воздействуя должным образом на них, поэтому для всех практических целей и задач оно будет казаться «зависшим» без признания Windows, что оно не отвечает.
Windows - операционная система, она контролирует все запущенные программы.
Windows связывается с оконными приложениями, используя события. Каждая программа имеет поток, который постоянно прослушивает входящие события и обрабатывает их. Например, когда вы нажимаете кнопку или значок области уведомлений, Windows генерирует событие и передает его в соответствующий процесс. Затем процесс может решить, как с этим справиться.
Все взаимодействия с программами основаны на событиях в Windows, поэтому, когда программа не обрабатывает входящие события слишком долго, это означает, что она не отвечает. Как @DavidPostill нашел и отметил в своем ответе , время ожидания составляет 5 секунд. PeekMessage
это функция, которая получает событие из очереди событий.
Ответ на ваш вопрос - да / нет.
В то время как ОС Windows может опрашивать и обрабатывать приложения с событиями в очереди сообщений Windows, программы абсолютно не обязаны устанавливать связь с WinAPI или обрабатывать / отвечать на очередь Windows. Даже ответ на сообщение в очереди не говорит Windows, была ли программа «заблокирована» или нет. Это показатель, но это все, что есть. Реальный ответ немного сложнее.
Настоящий ответ
Люди обдумывают фактический ответ здесь. Определение того, «не отвечает» ли программа, является вариантом « проблемы остановки », которая формально неразрешима в компьютерной науке. Краткое объяснение состоит в том, что процессор не может выступать в роли третьей стороны, наблюдающей за собой, чтобы определить, застряла ли подпрограмма в бесконечном цикле, ничего не делая против увеличения счетчика, который завершится на некотором фиксированном, нормальном числе. Оба из них можно считать плотно замкнутыми петлями. Один останавливается, другой никогда не закончится. Даже вы, как человек, не знаете, отвечает ли программа на самом деле или нет, особенно если она находится в плотно замкнутом цикле - вы знаете только, если считаете, что она должна (отвечать).
С точки зрения Windows, оба этих цикла «не отвечают» . Вот почему Windows дает вам выбор ждать или завершить, потому что он не может сказать.
Таким образом, следствие является «почему окна знают , что процесс будет отвечать?» Ответ довольно умный. Когда процесс компилируется в многопоточной и многопроцессорной ОС, иногда даже в сильно замкнутых циклах, компилятор может добавить команду yield () , которая предоставляет удобное уведомление процессору, что он может переключиться на другие запущенные процессы , Это «отдает» процессор и «переключение контекста» (как его называют) бывает , что позволяет ОС (Windows включен) , чтобы ответить на другие события в стеке, некоторые из которых включают в себя отслеживание , что процесс уже ответил.
** Это не означает, что процесс ответа будет прекращен . ** Процесс внутри бесконечного цикла может дать процессор, позволяющий Windows обрабатывать другие события.
В некоторых программах Windows программа обрабатывает сигналы ОС Windows, которые могут сообщить ОС, что она «отвечает», но ни одна программа не обязана это делать. Вы можете написать довольно простую загрузку процессора, программы без прерывания даже на языках более высокого уровня в Windows, таких как perl, php, python и Windows, которые могут не обнаружить, что он не завершает работу и не отвечает. В этот момент Windows зависит от эвристики - загрузки процессора, памяти, сколько прерываний обработал процессор, пока программа «угадывала». Опять же, в этот момент Windows должна попросить вас прекратить работу, потому что она действительно не знает, должна ли она.
Смотрите также ответ Виктора (правильный). Не обращайте внимания на комментарии о том, не «не отвечает» не то же самое, что бесконечный цикл. Существуют всевозможные сообщения, прерывания, циклы, которые приложение может обрабатывать или не обрабатывать без уведомления очереди сообщений Windows. Обработка очереди сообщений - это только один из многих видов событий, на которые ОС ведет счетчики, пытаясь угадать , завис ли процесс.