@ magicandre1981 Essa página propõe uma maneira de verificar se um programa está fazendo algo ativamente, mas não é o que o Windows realmente usa.
precisa saber é o seguinte
Olhe para a fila de mensagens do Windows, um candidato é a função PeekMessage ()
Luciano
Respostas:
150
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.
↑ Isso. Nada a ver com o planejamento ou com o sugerido na resposta aceita, apenas se você ligar regularmente GetMessage(ou algo semelhante) e DispatchMessage.
Damon
1
A resposta aceita, ao se referir IsHungAppWindowcorretamente, observa que um programa na fase de inicialização não precisa chamar GetMessage.
MSalters 25/08/15
@MSalters Com a inicialização definida como o tempo anterior ao primeiro GetMessage? Esse recurso permite que aplicativos simples de linha de comando funcionem sem serem considerados travados, pois não precisam pesquisar a fila.
catraca aberração
4
@ratchetfreak: presumivelmente antes da primeira chamada do CreateWindow. Aplicativos de linha de comando são completamente diferentes; eles estão rodando dentro do ConHost.EXE e interage com o susbystem da GUI do Windows para eles.
MSalters
1
Além disso, parece-me que, no Windows 7 (e possivelmente antes), o Windows perceberá isso muito mais cedo se você tentar e não conseguir manipular a janela de alguma forma. como se um programa não processa uma mensagem de maximização ou movimento, o Windows 7 vai saltar direito de não responder após cerca de 1 ou 2 segundos ..
Dave Cousineau
78
Como o Windows sabe se um programa não está respondendo?
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.
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.
O estado travar não é baseado na CPU. A maioria dos programas é "travada" nesse sentido por 99,999% do tempo e não faz nada.
usr
2
@usr Onde eu disse que "travou" depende da CPU?
DavidPostill
2
@usr A primeira metade da resposta está respondendo "Ele continua pesquisando constantemente todos os aplicativos em execução?". A segunda metade está respondendo "Como o Windows sabe se um programa não está respondendo ?. O OP fez duas perguntas em uma;)
DavidPostill
9
Não é realmente uma votação, porém, é? Suponho que os internos são mais como um identificador de espera na janela é sinalizado quando você liga 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.
Luaan 24/08/2015
2
Você pode excluir tudo acima de "Sobre mensagens e filas de mensagens", pois isso não ajuda na resposta. O Windows sabe que um aplicativo parou de responder porque para de enviar mensagens. O aplicativo pode estar sendo executado, pois está fazendo algo intensivo em vez de enviar mensagens (mas isso é um programa mal projetado).
Andy
32
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.
Não responder, por definição, significa não processar mensagens da janela, por isso não se aplica a serviços ou aplicativos de console, e eu diria que o Windows sempre sabe se um aplicativo não está respondendo. Você está confundindo bloqueios e não está respondendo.
Andy
Obviamente, ele pode saber se um programa não está respondendo. "Não responder" não é o mesmo que "preso em um loop infinito"
BlueRaja - Danny Pflughoeft
1
Na verdade, um aplicativo pode recuperar mensagens via GetMessage () e falhar ao processá-las, e não seria reconhecido como "não respondendo" pelo Windows, apesar de certamente parecer não responder ao usuário. O termo "não responder" também é frequentemente usado para descrever aplicativos de rede, serviço, linha de comando interativa etc. AFAIK não existe uma definição formal que limite a frase a aplicativos em janela. Um impasse ou um loop infinito (ou qualquer outro erro de programação) pode fazer com que um aplicativo fique sem resposta, mas não, não confundi causa e efeito.
precisa saber é o seguinte
10
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.
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.
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.
fonte
GetMessage
(ou algo semelhante) eDispatchMessage
.IsHungAppWindow
corretamente, observa que um programa na fase de inicialização não precisa chamarGetMessage
.GetMessage
? Esse recurso permite que aplicativos simples de linha de comando funcionem sem serem considerados travados, pois não precisam pesquisar a fila.Como o Windows sabe se um programa não está respondendo?
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
IsHungAppWindow
que pode ser usada.Função IsHungAppWindow de origem
Origem sobre mensagens e filas de mensagens
Ele continua pesquisando constantemente todos os aplicativos em execução?
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) .
fonte
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.
fonte
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.fonte
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.
fonte