Como o Windows sabe se um programa não está respondendo? Ele continua pesquisando constantemente todos os aplicativos em execução?
Como o Windows sabe se um programa não está respondendo? Ele continua pesquisando constantemente todos os aplicativos em execução?
Respostas:
Um aplicativo obtém os eventos de uma fila fornecida pelo Windows.
Se o aplicativo não pesquisar a fila de eventos por um tempo (5 segundos), por exemplo, ao fazer um cálculo longo, o Windows assume que o aplicativo está travado e alerta o usuário.
Para evitar que os aplicativos enviem cálculos caros para os threads de trabalho ou divida o processamento e verifique se a fila é pesquisada regularmente.
GetMessage(ou algo semelhante) e DispatchMessage.
IsHungAppWindowcorretamente, observa que um programa na fase de inicialização não precisa chamar GetMessage.
GetMessage? Esse recurso permite que aplicativos simples de linha de comando funcionem sem serem considerados travados, pois não precisam pesquisar a fila.
Sem o código fonte do Windows, não podemos ter certeza do que ele está fazendo internamente.
Há uma função do Windows SDK IsHungAppWindowque pode ser usada.
Considera-se que um aplicativo não está respondendo se não estiver aguardando entrada, não estiver em processamento de inicialização e não tiver chamado PeekMessage dentro do período de tempo limite interno de 5 segundos.
Função IsHungAppWindow de origem
Se uma janela de nível superior parar de responder às mensagens por mais de alguns segundos, o sistema considerará que a janela não está respondendo. Nesse caso, o sistema oculta a janela e a substitui por uma janela fantasma que possui a mesma ordem Z, local, tamanho e atributos visuais. Isso permite ao usuário movê-lo, redimensioná-lo ou até fechar o aplicativo. No entanto, essas são as únicas ações disponíveis porque o aplicativo realmente não está respondendo.
Origem sobre mensagens e filas de mensagens
Não. Os aplicativos não são pesquisados, mas recebem tempo do processador.
O Windows possui um sistema de agendamento que fornece tempo ao processador para os threads do aplicativo.
O algoritmo de agendamento é complexo e está totalmente descrito em Windows Internals, Parte 1 (6ª Edição) (Referência do Desenvolvedor) .
PeekMessage. Portanto, quando o Windows envia uma mensagem ao aplicativo e não é sinalizado em cinco segundos, ele marca o aplicativo como não respondendo. E, de fato, no Windows mais recente, a janela é marcada como "não está respondendo" se não responder à entrada do usuário a tempo - até eu tentar clicar ou pressionar uma tecla ou algo assim, o aplicativo pode facilmente ficar "travado" por minutos sem "aparecer" sem resposta.
Na verdade, o Windows nem sempre sabe que um aplicativo não está respondendo. O aplicativo deve ser um aplicativo interativo com uma janela e a janela deve estar recebendo mensagens que o aplicativo falha ao processar, antes que o Windows conclua que o aplicativo não está respondendo.
Por exemplo, o Windows não tem como saber se um aplicativo de processamento de números sem interface de usuário que é executado a partir da linha de comando está funcionando, ou se está preso a um loop infinito.
Aplicativos gráficos interativos no Windows recebem eventos pesquisando continuamente uma fila de mensagens. O Windows preenche essa fila de mensagens com eventos de teclado, mouse, timer, etc. Se um aplicativo falhar em pesquisar a fila de mensagens por algum tempo (5 segundos é o tempo limite mencionado na documentação da função IsHungAppWindow ()), o Windows considerará o aplicativo "travado", o que pode indicar alterando o título da janela (adicionando o texto " (Não está respondendo) "ou texto equivalente em versões localizadas) e acinzentando o conteúdo da janela se o usuário tentar interagir com a janela.
Os aplicativos podem travar de maneiras que o Windows não reconhece. Por exemplo, um aplicativo pode continuar pesquisando mensagens em sua fila de mensagens sem agir adequadamente sobre elas; portanto, para todos os propósitos e propósitos práticos, ele pareceria "travado" sem que o Windows reconhecesse que não responde.
O Windows é um sistema operacional, está supervisionando todos os programas em execução.
O Windows se comunica com aplicativos baseados em janelas usando eventos. Todo programa tem um encadeamento que constantemente escuta os eventos recebidos e os processa. Por exemplo, quando você clica em um botão ou em um ícone da área de notificação, o Windows gera um evento e o alimenta no processo apropriado. O processo pode então decidir como lidar com isso.
Todas as interações com programas são baseadas em eventos no Windows; portanto, quando o programa não processa os eventos recebidos por muito tempo, isso significa que não responde. Como o @DavidPostill encontrou e observou em sua resposta , o tempo limite é de 5 segundos. PeekMessageé a função que obtém um evento da fila de eventos.
A resposta para sua pergunta é sim / não.
Enquanto o sistema operacional Windows pode e faz pesquisa de aplicativos com eventos na Fila de Mensagens do Windows, os programas têm absolutamente nenhuma obrigação de vincular à WinAPI ou manipular / responder à Fila do Windows. Mesmo responder a uma mensagem na Fila não informa ao Windows se o programa "travou" ou não. É um indicador, mas é só isso. A resposta real é um pouco mais complicada.
A verdadeira resposta
As pessoas estão se aproximando da resposta real aqui. Determinar se um programa "não está respondendo" é uma variante do " problema de parada ", formalmente indecidível na ciência da computação. A breve explicação é que o processador não pode agir como um terceiro observando a si mesmo para determinar se uma sub-rotina está presa em um loop infinito, sem fazer nada contra incrementar um contador que terminará em algum número fixo e normal. Ambos podem ser considerados loops bem fechados. Um pára, o outro nunca termina. Mesmo você, como pessoa, não sabe se um programa está realmente respondendo ou não, especialmente se estiver em um loop bem fechado - você só sabe se acha que deve (responder).
Do ponto de vista do Windows, esses dois loops "não estão respondendo" . É por isso que o Windows oferece a você a opção de esperar ou terminar, porque não pode dizer.
Portanto, o corolário é "por que o Windows sabe que um processo está respondendo?" A resposta é bastante inteligente. Quando um processo é compilado em um sistema operacional multiencadeado e com vários processos, às vezes até em loops bem fechados, o compilador pode adicionar um comando yield () , que fornece uma notificação conveniente ao processador de que ele pode alternar para outros processos em execução . Ele "dá-se" o processador e uma "mudança de contexto" (como é chamado) acontece que permite que o OS (Windows incluído) para responder a outros eventos na pilha, alguns dos quais incluem rastreamento que o processo tenha respondido.
** Isso não significa que um processo de resposta será encerrado . ** Um processo dentro de um loop infinito pode render o processador, permitindo que o Windows processe outros eventos.
Em alguns programas do Windows, o programa manipula os sinais do sistema operacional Windows, que podem dizer ao sistema operacional que "está respondendo", mas nenhum programa tem obrigação de fazê-lo. Você pode escrever programas simples e sem interrupção da CPU, mesmo em linguagens de nível superior no Windows, como perl, php, python e Windows, e pode não detectar que não está finalizando e não está respondendo. Nesse ponto, o Windows depende das heurísticas - carga da CPU, memória, quantas interrupções o processador manipulou enquanto o programa estava sendo executado para "adivinhar". Novamente, nesse ponto, o Windows precisa solicitar que você termine, porque realmente não sabe se deve.
Veja também a resposta de Viktor (correta). Ignore os comentários sobre se "não responder" não é o mesmo que um loop infinito. Existem todos os tipos de mensagens, interrupções e loops que um aplicativo pode ou não manipular sem informar a fila de mensagens do Windows. O tratamento da fila de mensagens é apenas um dos muitos tipos de eventos em que o SO mantém contadores para tentar adivinhar se um processo está travado.