Come fa Windows a sapere se un programma non risponde? Continua a eseguire il polling costante di tutte le applicazioni in esecuzione?
Come fa Windows a sapere se un programma non risponde? Continua a eseguire il polling costante di tutte le applicazioni in esecuzione?
Risposte:
Un'applicazione ottiene gli eventi da una coda fornita da Windows.
Se l'applicazione non esegue il polling del eventqueue per un po '(5 secondi), ad esempio quando si esegue un lungo calcolo, Windows presume che l'applicazione sia bloccata e avvisa l'utente.
Per evitare che le applicazioni debbano inviare costosi calcoli ai thread di lavoro o suddividere l'elaborazione e assicurarsi che la coda venga regolarmente interrogata.
GetMessage
(o simili) e DispatchMessage
.
IsHungAppWindow
nota corretta, non è necessario chiamare un programma in fase di avvio GetMessage
.
GetMessage
? Questa funzionalità consente alle semplici app della riga di comando di funzionare senza essere considerate bloccate in quanto non è necessario eseguire il polling della coda.
Senza il codice sorgente di Windows non possiamo essere sicuri di cosa stia facendo internamente.
È IsHungAppWindow
possibile utilizzare una funzione SDK per Windows .
Un'applicazione è considerata non rispondere se non è in attesa di input, non è in fase di elaborazione all'avvio e non ha chiamato PeekMessage entro il periodo di timeout interno di 5 secondi.
Funzione IsHungAppWindow di origine
Se una finestra di livello superiore smette di rispondere ai messaggi per più di alcuni secondi, il sistema considera che la finestra non risponde. In questo caso, il sistema nasconde la finestra e la sostituisce con una finestra fantasma che ha lo stesso ordine Z, posizione, dimensione e attributi visivi. Ciò consente all'utente di spostarlo, ridimensionarlo o persino chiudere l'applicazione. Tuttavia, queste sono le uniche azioni disponibili perché l'applicazione in realtà non risponde.
Fonte di messaggi e code di messaggi
No. Le applicazioni non vengono sottoposte a polling ma al tempo del processore.
Windows ha un sistema di pianificazione che offre tempo di elaborazione ai thread dell'applicazione.
L'algoritmo di pianificazione è complesso ed è completamente descritto in Windows Internals, Part 1 (6th Edition) (Riferimenti per gli sviluppatori) .
PeekMessage
. Pertanto, quando Windows invia un messaggio all'applicazione e non viene segnalato entro cinque secondi, contrassegna l'applicazione come non rispondente. E infatti, su Windows più recente, la finestra è contrassegnata come "non risponde" solo se non è riuscita a rispondere in tempo all'input dell'utente - finché non provo a fare clic o premere un tasto o qualcosa, l'applicazione può facilmente rimanere "bloccata" per minuti senza "apparire" non reattivo.
In realtà, Windows non sempre sa che un'applicazione non risponde. L'applicazione deve essere un'applicazione interattiva con una finestra e la finestra deve ricevere messaggi che l'applicazione non riesce a elaborare, prima che Windows concluda che l'applicazione non risponde.
Ad esempio, Windows non ha modo di sapere se un'applicazione che esegue il crunch del numero senza interfaccia utente che viene eseguita dalla riga di comando sta facendo la sua cosa, o forse bloccato in un ciclo infinito.
Le applicazioni grafiche interattive in Windows ricevono eventi eseguendo il polling continuo di una coda di messaggi. Windows popola questa coda di messaggi con eventi tastiera, mouse, timer, ecc. Se un'applicazione non riesce a eseguire il polling della coda dei messaggi per un certo periodo di tempo (5 secondi è il timeout menzionato nella documentazione della funzione IsHungAppWindow ()), Windows considera l'applicazione "bloccata", che può indicare modificando il titolo della finestra (aggiungendo il testo " (Not Responding) "o testo equivalente nelle versioni localizzate) e ingrigire il contenuto della finestra se l'utente tenta di interagire con la finestra.
Le applicazioni possono bloccarsi in modi che Windows non riconosce. Ad esempio, un'applicazione può continuare a eseguire il polling dei messaggi nella sua coda di messaggi senza agire correttamente su di essi, quindi a tutti gli effetti pratici sembrerebbe "bloccata" senza che Windows riconosca che non risponde.
Windows è un sistema operativo, sta supervisionando tutti i programmi in esecuzione.
Windows comunica con le applicazioni basate su finestre tramite eventi. Ogni programma ha un thread che ascolta costantemente gli eventi in arrivo e li elabora. Ad esempio, quando si fa clic su un pulsante o sull'icona di un'area di notifica, Windows genera un evento e lo inserisce nel processo appropriato. Il processo può quindi decidere come gestirlo.
Tutte le interazioni con i programmi sono basate su eventi in Windows, quindi quando il programma non elabora gli eventi in arrivo per troppo tempo, significa che non risponde. Come ha trovato e notato @DavidPostill nella sua risposta , il timeout è di 5 secondi. PeekMessage
è la funzione che ottiene un evento dalla coda degli eventi.
La risposta alla tua domanda è sì / NO.
Mentre il sistema operativo Windows può eseguire il polling delle applicazioni con eventi nella coda di messaggistica di Windows, i programmi hanno l'obbligo assolutamente zero di collegarsi a WinAPI o gestire / rispondere alla coda di Windows. Anche rispondere a un messaggio nella coda non dice a Windows se il programma è "bloccato" o no. È un indicatore, ma è tutto. La vera risposta è un po 'più complicata.
La vera risposta
Le persone si nascondono intorno alla risposta effettiva qui. Determinare se un programma "non risponde" è una variante del " problema di arresto ", che è formalmente indecidibile in informatica. La breve spiegazione è che il processore non può agire come una terza parte osservandosi per determinare se una subroutine è bloccata in un ciclo infinito, senza fare nulla contro incrementare un contatore che terminerà con un numero normale fisso. Entrambi possono essere considerati come anelli strettamente chiusi. Uno si ferma, l'altro non si chiuderà mai. Anche tu, come persona, non sai se un programma sta effettivamente rispondendo o meno, specialmente se è in un circuito strettamente chiuso - sai solo se pensi che dovrebbe (rispondere).
Dal punto di vista di Windows, entrambi questi loop "non rispondono" . Ecco perché Windows ti dà la possibilità di aspettare o terminare, perché non può dirlo.
Quindi il corollario è "perché Windows sa che un processo sta rispondendo?" La risposta è piuttosto intelligente. Quando un processo viene compilato in un sistema operativo multi-thread e multi-processo, a volte anche in loop ben chiusi, il compilatore può aggiungere un comando yield () , che fornisce una notifica conveniente al processore che può passare ad altri processi in esecuzione . E ' "rinuncia" del processore e di un "cambio di contesto" (come viene chiamato) accade che permette al sistema operativo (Windows incluso) per rispondere ad altre manifestazioni nella pila, alcuni dei quali includono il monitoraggio che il processo si è risposto.
** Ciò non significa che un processo di risposta verrà interrotto . ** Un processo all'interno di un ciclo infinito può produrre il processore, consentendo a Windows di elaborare altri eventi.
In alcuni programmi Windows, il programma gestirà i segnali del sistema operativo Windows, il che può dire al sistema operativo che "risponde", ma nessun programma ha l'obbligo di farlo. È possibile scrivere programmi di hogging della CPU abbastanza semplici, anche non terminanti, anche all'interno di linguaggi di livello superiore su Windows come perl, php, python e Windows potrebbero non rilevare che non sta terminando e non risponde. A quel punto, Windows dipende dall'euristica: carico della CPU, memoria, quante interruzioni vengono gestite dal processore mentre il programma era in esecuzione per "indovinare". Ancora una volta, a quel punto, Windows deve chiederti di terminare, perché in realtà non sa se dovrebbe.
Vedi anche la risposta (corretta) di Viktor. Ignora i commenti sul fatto che "non rispondere" non sia lo stesso di un ciclo infinito. Esistono tutti i tipi di messaggi, interruzioni, cicli che un'applicazione può o non può gestire senza informare la coda dei messaggi di Windows. La gestione della coda dei messaggi è solo uno dei molti tipi di eventi su cui il sistema operativo continua i contatori per provare a indovinare se un processo è bloccato.