Як Windows дізнається, що програма не відповідає?


174

Як Windows дізнається, що програма не відповідає? Чи постійно він продовжує опитувати всі запущені програми?



@ magicandre1981 На цій сторінці пропонується один із способів перевірити, що програма активно щось робить, але це не спосіб, яким Windows реально користується.
Кевін Панько

Подивіться на чергу повідомлень Windows, кандидатом є функція PeekMessage ()
Luciano

Відповіді:


150

Додаток отримує події з черги, наданої Windows.

Якщо програма деякий час (5 секунд) не запитує події на подію, наприклад, коли ви робите довгий розрахунок, тоді Windows передбачає, що додаток вивішене та попереджає користувача.

Щоб уникнути того, що додатки повинні підштовхувати дорогі обчислення до робочих ниток або розділяти обробку та стежити, щоб черга регулярно опитувалася.


27
↑ Це. Немає нічого спільного з плануванням або таким, як пропонується у прийнятій відповіді, лише ви регулярно телефонуєте GetMessage(або подібні) та DispatchMessage.
Деймон

1
Прийнята відповідь, посилаючись на IsHungAppWindowправильно зазначає, що програмі на етапі запуску не потрібно дзвонити GetMessage.
MSalters

@MSalters Якщо запуск визначається як час до першого GetMessage? Ця функція дозволяє простим програмам командного рядка працювати, не вважаючись висячими, оскільки їм не потрібно опитувати чергу.
щурячий вирод

4
@ratchetfreak: Імовірно, перед першим викликом CreateWindow. Додатки командного рядка взагалі різні звірі; вони працюють у ConHost.EXE і він взаємодіє з підсистемою інтерфейсу Windows GUI для них.
MSalters

1
Крім того, мені здається, що в Windows 7 (і, можливо, раніше) вікна помітять це набагато раніше, якщо ви спробуєте яким-небудь чином маніпулювати вікном. наприклад, якщо програма не обробляє повідомлення про максимізацію чи переміщення, Windows 7 підскочить праворуч, щоб не відповісти приблизно через 1 або 2 секунди ..
Дейв Кузіно,

78

Як Windows дізнається, що програма не відповідає?

Без вихідного коду для Windows ми не можемо бути впевнені, що він робить внутрішньо.

Існує функція SDK Windows, IsHungAppWindowяку можна використовувати.

Програма вважається такою, що не відповідає, якщо вона не чекає введення, не знаходиться в обробці запуску і не викликала PeekMessage протягом внутрішнього періоду очікування 5 секунд.

Джерело IsHungAppWindow функція

Якщо вікно верхнього рівня перестає реагувати на повідомлення більше декількох секунд, система вважає, що вікно не відповідає. У цьому випадку система приховує вікно і замінює його привидним вікном, яке має однакові атрибути Z порядку, розташування, розміру та візуальних атрибутів. Це дозволяє користувачеві перемістити його, змінити розмір або навіть закрити додаток. Однак це єдині доступні дії, оскільки програма насправді не реагує.

Джерело Про повідомлення та черги на повідомлення


Чи постійно він продовжує опитувати всі запущені програми?

Ні. Програми не опитуються, а задаються процесорним часом.

У Windows є система планування, яка надає процесорному часу потоки програм.

Алгоритм планування складний і повністю описаний у програмі Windows Internals, частина 1 (6-е видання) (Довідник розробника) .


2
Стан повішення не базується на процесорі. Більшість програм у цьому сенсі «висять» 99,999% часу і нічого не роблять.
usr

2
@usr Де я сказав, що "висів" залежить від процесора?
DavidPostill

2
@usr Перша половина відповіді відповідає "Чи постійно триває опитування всіх запущених програм?". Друга половина відповідає "Як Windows знає, що програма не відповідає? ОП
задало

9
Але це насправді не опитування, чи не так? Я припускаю, що внутрішні схожі на те, що ручка очікування на вікні сигналізується під час дзвінка PeekMessage. Тож, коли Windows надсилає повідомлення додатку, і не отримує сигналу протягом п’яти секунд, воно позначає програму невідповідною. Насправді, в останніх Windows вікно позначається лише "не реагує", якщо воно не вдалося вчасно реагувати на введення користувача - доки я не спробую натиснути або натиснути клавішу чи щось таке, додаток може легко залишатися "висячим" для хвилин, не з'являючись "невідповідально".
Луань

2
Ви можете видалити все вище "Про повідомлення та черги на повідомлення", оскільки це не допомагає відповісти. Windows знає, що програма перестала реагувати, оскільки вона перестає завантажувати повідомлення. Додаток може працювати, хоча він робить щось інтенсивне замість перекачування повідомлень (але це погано розроблена програма).
Енді,

32

Насправді, Windows не завжди знає, що програма не відповідає. Додаток має бути інтерактивною програмою з вікном, і вікно повинно отримувати повідомлення, які програма не обробляє, перш ніж Windows зробить висновок, що програма не відповідає.

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

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

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


8
Не відповідати, за визначенням, означає не обробляти віконні повідомлення, тому це не стосується служб або консольних програм, і тому я б сказав, що Windows завжди знає, що програма не відповідає. Ви плутаєте мертві замки та не реагуєте.
Енді

Звичайно, він може знати, якщо програма не відповідає. "Не реагувати" - це не те саме, що "застряг у нескінченному циклі"
BlueRaja - Danny Pflughoeft

1
Насправді програма може отримувати повідомлення через GetMessage () і не обробляти їх, і Windows не визнає "невідповідальним", незважаючи на те, що він, звичайно, не відповість користувачеві. Термін "не відповідає" також часто використовується для опису мережевих, службових, інтерактивних командних рядків тощо. Додатків; AFAIK не існує офіційного визначення, яке б обмежувало цю фразу віконними програмами. І тупик, або нескінченний цикл (або будь-яка інша помилка програмування) можуть призвести до того, що програма не реагує, але ні, я не плутав причину та наслідки.
Віктор Тот

10

Windows - це операційна система, вона контролює всі запущені програми.

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

Всі взаємодії з програмами базуються на подіях у Windows, тому коли програма не обробляє вхідні події занадто довго, це означає, що вона не реагує. Як @DavidPostill знайшов і зазначив у своїй відповіді , час очікування становить 5 секунд. PeekMessageце функція, яка отримує подію з черги подій.


0

Відповідь на ваше запитання - так / ні.

У той час як ОС Windows може і проводити опитування програм із подіями в черзі обміну повідомленнями Windows, програми не мають абсолютно нульового зобов’язання зв’язуватися з WinAPI або обробляти / відповідати черзі Windows. Навіть відповідь на повідомлення в черзі не повідомляє Windows, чи "програма заблокувалась" чи ні. Це показник, але це все. Справжня відповідь є дещо складнішою.

Справжній відповідь

Тут хеджуються фактичні відповіді. Визначення того, чи програма не відповідає ", є варіантом" проблеми зупинки ", формально не визначуваної в інформатиці. Коротке пояснення полягає в тому, що процесор не може діяти як сторона, що спостерігає за собою, щоб визначити, чи підпрограма застрягла в нескінченному циклі, нічого не роблячи проти збільшення лічильника, який закінчується на деякому фіксованому, нормальному кількості. І те і інше можна вважати щільно закритими петлями. Одна зупиняється, інша ніколи не припиняється. Навіть ви, як людина, не знаєте, реально реагує програма чи ні, особливо якщо вона знаходиться в щільно замкнутому циклі - ви знаєте лише, чи думаєте, що вона повинна (відповісти).

З точки зору Windows, обидві ці петлі "не відповідають" . Ось чому Windows дає вам можливість чекати або припиняти, оскільки він не може визначити.

Таким чином, слідство є «чому вікна знають , що процес буде відповідати?» Відповідь досить розумна. Коли процес компілюється у багатопотоковій та багатопроцесорній ОС, іноді навіть у щільно закритих циклах, компілятор може додати команду return () , яка забезпечує зручне повідомлення процесору, що він може переходити на інші запущені процеси . Це «віддає» процесор і «перемикання контексту» (як його називають) буває , що дозволяє ОС (Windows включений) , щоб відповісти на інші події в стеці, деякі з яких включають в себе відстеження , що процес уже відповів.

** Це не означає, що процес реагування закінчиться . ** Процес всередині нескінченного циклу може давати процесор, дозволяючи Windows обробляти інші події.

У деяких програмах Windows програма буде обробляти сигнали ОС Windows, які можуть сказати ОС, що вона "відповідає", але жодна програма не має жодних зобов'язань робити це. Ви можете писати досить прості процесори, не припиняючі програми, навіть у мовах вищого рівня в Windows, таких як perl, php, python та Windows, можливо, не виявлять, що він не закінчується і не відповідає. З цього моменту Windows залежить від евристики - завантаження процесора, пам’яті, кількості переривань процесора, обробленого під час роботи програми, щоб «здогадатися». Знову ж таки, в цей момент Windows має попросити вас припинити дію, оскільки вона справді не знає, чи слід.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.