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

174

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

ArunPrasanth
источник
@ magicandre1981 На этой странице предлагается один из способов проверки того, что программа активно что-то делает, но это не тот способ, которым на самом деле использует Windows.
Кевин Панко
Посмотрите на очередь сообщений Windows, кандидатом является функция PeekMessage ()
Лучано

Ответы:

150

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

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

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

чокнутый урод
источник
27
↑ это. Ничего общего с расписанием или с тем, что предлагается в принятом ответе, только если вы регулярно звоните GetMessage(или тому подобное) и DispatchMessage.
Деймон
1
Принятый ответ, при обращении к IsHungAppWindowправильно отмечаемым, что программе на этапе запуска не нужно вызывать GetMessage.
MSalters
@MSalters С запуском определяется как время до первого GetMessage? Эта функция позволяет простым приложениям командной строки работать без зависания, поскольку им не нужно опрашивать очередь.
фрик с трещоткой
4
@ratchetfreak: предположительно перед первым вызовом CreateWindow. Приложения командной строки - это разные звери; они работают внутри ConHost.EXE, и он взаимодействует с ним для них в системе Windows GUI.
MSalters
1
Кроме того, мне кажется, что в Windows 7 (и, возможно, раньше) эти окна заметят это гораздо раньше, если вы попытаетесь каким-либо образом изменить окно. например, если программа не обрабатывает сообщение «развернуть» или «переместить», окна 7 будут прыгать вправо, не отвечая примерно через 1 или 2 секунды ..
Дейв Кузино,
78

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

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

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

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

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

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

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


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

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

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

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

ДэвидПостилл
источник
2
Состояние зависания не зависит от процессора. В этом смысле большинство программ «зависают» в течение 99,999% времени и ничего не делают.
USR
2
@usr Где я сказал, что зависание зависит от процессора?
ДэвидПостилл
2
@usr Первая половина ответа - «Постоянно ли опрашиваются все запущенные приложения?». Вторая половина отвечает на вопрос: «Как Windows узнает, что программа не отвечает?». ОП задал два вопроса в одном;)
DavidPostill
9
Это не совсем опрос, правда? Я предполагаю, что внутреннее устройство больше похоже на дескриптор ожидания в окне, когда вы звоните PeekMessage. Поэтому, когда Windows отправляет сообщение приложению и не получает сигнал в течение пяти секунд, оно помечает приложение как не отвечающее. И на самом деле, в более поздних версиях Windows окно помечается как «не отвечающее» только в том случае, если оно не отвечает вовремя на ввод пользователя - пока я не попытаюсь щелкнуть или нажать клавишу или что-то еще, приложение может легко оставаться «зависшим» для минут без «появления» неотвечающих.
Луаан
2
Вы можете удалить все выше «О сообщениях и очередях сообщений», так как это не поможет в ответе. Windows знает, что приложение перестало отвечать на запросы, потому что оно перестает качать сообщения. Приложение может быть запущено, поскольку оно делает что-то интенсивное, а не прокачивает сообщения (но это плохо разработанная программа).
Энди
32

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

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

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

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

Виктор Тот
источник
8
Не отвечать по определению означает не обрабатывать оконные сообщения, поэтому это не относится к службам или консольным приложениям, и поэтому я бы сказал, что Windows всегда знает, не отвечает ли приложение. Ты путаешь мертвые замки и не отвечаешь.
Энди
Конечно, он может знать, не отвечает ли программа. «Не отвечать» - это не то же самое, что «застревать в бесконечном цикле»
BlueRaja - Дэнни Пфлугхофт
1
На самом деле, приложение может извлекать сообщения через GetMessage () и не обрабатывать их, и Windows не будет распознавать их как «не отвечающие», несмотря на то, что они, безусловно, будут не реагировать на действия пользователя. Термин «не отвечает» также часто используется для описания сети, службы, интерактивной командной строки и т. Д. Приложений; AFAIK нет формального определения, которое ограничивает фразу оконными приложениями. И тупик, или бесконечный цикл (или любая другая программная ошибка) могут привести к тому, что приложение перестает отвечать на запросы, но нет, я не перепутал причину и следствие.
Виктор Тот
10

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

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

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

gronostaj
источник
0

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

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

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

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

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

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

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

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

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

благословения
источник