¿Cómo sabe Windows si un programa no responde? ¿Sigue constantemente sondeando todas las aplicaciones en ejecución?
¿Cómo sabe Windows si un programa no responde? ¿Sigue constantemente sondeando todas las aplicaciones en ejecución?
Respuestas:
Una aplicación obtiene los eventos de una cola proporcionada por Windows.
Si la aplicación no sondea la cola de eventos por un tiempo (5 segundos), por ejemplo, al hacer un cálculo largo, Windows asume que la aplicación está bloqueada y alerta al usuario.
Para evitar que las aplicaciones deban enviar costosos cálculos a subprocesos de trabajo o dividir el procesamiento y asegurarse de que la cola se sondee regularmente.
GetMessage
(o algo similar) y DispatchMessage
.
IsHungAppWindow
correctamente, señala que un programa en la fase de inicio no tiene que llamar GetMessage
.
GetMessage
? Esa característica permite que las aplicaciones de línea de comandos simples funcionen sin ser consideradas bloqueadas, ya que no necesitan sondear la cola.
Sin el código fuente de Windows no podemos estar seguros de lo que está haciendo internamente.
Hay una función SDK de Windows IsHungAppWindow
que se puede usar.
Se considera que una aplicación no responde si no está esperando la entrada, no está en proceso de inicio y no ha llamado a PeekMessage dentro del período de tiempo de espera interno de 5 segundos.
Función de origen IsHungAppWindow
Si una ventana de nivel superior deja de responder a los mensajes durante más de varios segundos, el sistema considera que la ventana no responde. En este caso, el sistema oculta la ventana y la reemplaza por una ventana fantasma que tiene el mismo orden Z, ubicación, tamaño y atributos visuales. Esto permite al usuario moverlo, cambiar su tamaño o incluso cerrar la aplicación. Sin embargo, estas son las únicas acciones disponibles porque la aplicación en realidad no responde.
Fuente sobre mensajes y colas de mensajes
No. Las aplicaciones no se sondean pero se les da tiempo de procesador.
Windows tiene un sistema de programación que le da tiempo al procesador para los subprocesos de la aplicación.
El algoritmo de programación es complejo y se describe completamente en Windows Internals, Parte 1 (6ta edición) (Referencia del desarrollador) .
PeekMessage
. Entonces, cuando Windows envía un mensaje a la aplicación y no se señala en cinco segundos, marca que la aplicación no responde. Y, de hecho, en Windows más reciente, la ventana solo está marcada como "no responde" si no responde a tiempo a la entrada del usuario , hasta que intente hacer clic o presionar una tecla o algo, la aplicación puede permanecer "colgada" fácilmente minutos sin "aparecer" sin respuesta.
En realidad, Windows no siempre sabe que una aplicación no responde. La aplicación debe ser una aplicación interactiva con una ventana, y la ventana debe estar recibiendo mensajes que la aplicación no puede procesar, antes de que Windows concluya que la aplicación no responde.
Por ejemplo, Windows no tiene forma de saber si una aplicación de cálculo numérico sin interfaz de usuario que se ejecuta desde la línea de comandos está haciendo lo suyo, o tal vez atascada en un bucle infinito.
Las aplicaciones gráficas interactivas en Windows reciben eventos al sondear continuamente una cola de mensajes. Windows llena esta cola de mensajes con eventos de teclado, mouse, temporizador, etc. Si una aplicación no puede sondear la cola de mensajes durante algún tiempo (5 segundos es el tiempo de espera mencionado en la documentación de la función IsHungAppWindow ()), Windows considera la aplicación "bloqueada", lo que puede indicar cambiando el título de la ventana (agregando el texto " (Sin respuesta) "o texto equivalente en versiones localizadas) y atenuando el contenido de la ventana si el usuario intenta interactuar con la ventana.
Las aplicaciones pueden bloquearse de formas que Windows no reconoce. Por ejemplo, una aplicación puede continuar sondeando mensajes en su cola de mensajes sin actuar adecuadamente sobre ellos, por lo que para todos los propósitos prácticos parecería "colgado" sin que Windows reconozca que no responde.
Windows es un sistema operativo, supervisa todos los programas en ejecución.
Windows se comunica con aplicaciones basadas en ventanas mediante eventos. Cada programa tiene un hilo que escucha constantemente los eventos entrantes y los procesa. Por ejemplo, cuando hace clic en un botón o en un ícono de área de notificación, Windows genera un evento y lo alimenta al proceso apropiado. El proceso puede decidir cómo manejarlo.
Todas las interacciones con los programas se basan en eventos en Windows, por lo que cuando el programa no procesa los eventos entrantes durante demasiado tiempo, significa que no responde. Como @DavidPostill ha encontrado y anotado en su respuesta , el tiempo de espera es de 5 segundos. PeekMessage
es la función que obtiene un evento de la cola de eventos.
La respuesta a su pregunta es sí / NO.
Si bien el sistema operativo Windows puede sondear aplicaciones con eventos en la Cola de mensajería de Windows, los programas tienen la obligación absolutamente nula de vincularse a WinAPI o manejar / responder la Cola de Windows. Incluso responder un mensaje en la Cola no le dice a Windows si el programa se ha "bloqueado" o no. Es un indicador, pero eso es todo. La verdadera respuesta es bastante más complicada.
La verdadera respuesta
La gente está evadiendo la respuesta real aquí. Determinar si un programa "no responde" es una variante del " problema de detención ", que es formalmente indecidible en informática. La explicación breve es que el procesador no puede actuar como un tercero observándose a sí mismo para determinar si una subrutina está atascada en un bucle infinito, sin hacer nada frente a incrementar un contador que terminará en un número fijo normal. Ambos pueden considerarse bucles cerrados. Uno se detiene, el otro nunca terminará. Incluso usted, como persona, no sabe si un programa realmente está respondiendo o no, especialmente si está en un ciclo cerrado, solo sabe si cree que debería (responder).
Desde la perspectiva de Windows, ambos bucles "no responden" . Es por eso que Windows le da la opción de esperar o finalizar, porque no puede decirlo.
Entonces, el corolario es "¿por qué Windows sabe que un proceso está respondiendo?" La respuesta es bastante inteligente. Cuando se compila un proceso en un sistema operativo multiproceso y multiproceso, a veces incluso en bucles muy cerrados, el compilador puede agregar un comando yield () , que proporciona una notificación conveniente al procesador de que puede cambiar a otros procesos en ejecución . "Renuncia" al procesador y ocurre un "cambio de contexto" (como se le llama) que permite que el sistema operativo (incluido Windows) responda a otros eventos en la pila, algunos de los cuales incluyen el seguimiento de que el proceso ha respondido.
** Esto no significa que un proceso de respuesta terminará . ** Un proceso dentro de un bucle infinito puede generar el procesador, permitiendo que Windows procese otros eventos.
En algunos programas de Windows, el programa manejará las señales del sistema operativo Windows, que pueden indicarle al sistema operativo que está "respondiendo", pero ningún programa tiene la obligación de hacerlo. Puede escribir programas de acaparamiento de CPU bastante simples, sin terminación, incluso dentro de lenguajes de nivel superior en Windows, como perl, php, python, y Windows puede no detectar que no está terminando y no responde. En ese punto, Windows depende de la heurística: carga de la CPU, memoria, cuántas interrupciones manejó el procesador mientras el programa se estaba ejecutando para "adivinar". Nuevamente, en ese punto, Windows tiene que pedirle que termine, porque realmente no sabe si debería hacerlo.
Ver también la respuesta (correcta) de Viktor. Ignore los comentarios sobre si "no responder" no es lo mismo que un bucle infinito. Hay todo tipo de mensajes, interrupciones, bucles que una aplicación puede o no manejar sin informar la cola de mensajes de Windows. El manejo de la cola de mensajes es solo uno de los muchos tipos de eventos en los que el sistema operativo mantiene los contadores para tratar de adivinar si un proceso está bloqueado.