fundo
No ano passado, compilei um sistema portátil de blog / servidor da web que posso executar a partir de uma unidade flash. É ótimo e funciona maravilhosamente, especialmente no XP. O problema é que, quando executado no Windows 7, cada programa de console gera dois processos, o próprio processo, além de uma cópia do conhost.exe
.
Problema
No caso do sistema de blog portátil, cada um de seus componentes de servidor (MySQL mysqld.exe
, duas instâncias do Apache, duas instâncias do httpd.exe
VisualSVN visualsvnserver.exe
e várias instâncias do PHP php-cgi.exe
) gera uma instância de conhost.exe
. Neste momento (sem cópias de php-cgi.exe
ativo, tenho cinco instâncias de conhost.exe
execução, usando quase nenhum ciclo de CPU, mas consumindo 22 MB de memória (além dos 80 MB que os processos atuais estão usando atualmente)).
Pesquisa
Como o Windows 7 foi lançado (e eu acho que possivelmente desde Vista), eu tenho em várias ocasiões tentou descobrir exatamente qual o propósito dos vários processos (novo) hospedeiro (por exemplo, conhost.exe
, dllhost.exe
e taskhost.exe
) fazer e se eles são realmente necessários. Tentei matá-los e descobri que os programas do console continuam funcionando, tanto para programas que usam uma janela do console quanto para aqueles que não usam (como servidores).
Eu já estou familiarizado com todo o csrss.exe
Windows Vistaconhost.exe
e já vi essa mesma explicação (quase literalmente) várias vezes. O problema é que todo mundo simplesmente copia e cola a mesma explicação que não ajuda. Tudo o que diz é que, no XP, aplicativos de console onde "hospedados por" ou "executados em" csrss.exe
, mas no Windows 7, eles foram movidos conhost.exe
para segurança. O aspecto da segurança faz sentido, mas não diz nada sobre o que significa hospedá-lo ou por que / quando é necessário (ou se é possível evitá-lo se não for necessário). Até a discussão de Raymond Chen encobre o motivo pelo qual os aplicativos de console são hospedados de maneira diferente.
A coisa mais próxima que posso encontrar de uma explicação técnica detalhada é uma publicação no blog da Microsoft que parece reforçar a ideia de que é apenas sobre a GUI e a janela do aplicativo do console. Isso me deixa pensando ainda mais se conhost.exe
é necessário para programas sem janelas como esses servidores. Se não há nenhuma janela, por que devo desperdiçar recursos e encher o espaço de processos com processos desnecessários? Por que o Windows não pode detectar quando é desnecessário e evitá-lo? A resposta do SecurityMatt também foi um pouco útil no que diz respeito a uma explicação técnica, mas, novamente, não são suficientes as informações que estou procurando.
Eu não sou o único que tentou descobrir uma maneira de parar instâncias desnecessárias de conhost
. Essa pessoa perguntou sobre desativá-lo e foi-lhe dito simplesmente "não é possível" sem nenhum esforço ou pensamento adicional. Hugh D e "Dificilmente um recurso" apontaram o problema com várias instâncias redundantes de conhost
(pelo menos com csrss
apenas uma cópia em execução), incluindo o uso de recursos e as instâncias remanescentes após o término dos processos filhos. Laufer questionou se / quando é necessário.
Observações e tentativas de solução
Se eles não forem realmente necessários o tempo todo (novamente, eu não vi nenhum efeito prejudicial ao matá-los), então suponho que eu poderia (muito irritante) contornar o problema substituindo os servidores por arquivos em lote que os executam. , aguarde e, em seguida, mate a cópia do conhost
que eles causam a execução. Obviamente, isso requer uma maneira rápida e fácil de determinar qual é. FallenGameR perguntou como obter a instância de conhost.exe
associado a um programa de console de um determinado PID, mas não obteve resposta. Eu acho que a simples recuperação do PID do processo pai deve funcionar (não, o ProcessExplorer não é uma opção, um sistema automatizado / com script)é necessária), mas isso não apenas exigiria a criação de algum tipo de estrutura para obter o PID do filho (em vez de simplesmente executá-lo e concluir a tarefa), mas também significaria descobrir uma maneira de torná-lo compatível com o XP também (por exemplo, verificando o nome da imagem do processo pai). Esta postagem do blog mostra uma maneira, mas requer o PowerShell e dificilmente é ideal, sem mencionar que não diz nada sobre as implicações da execução do script.
Questões)
Talvez a Microsoft pense que ninguém mais usa prompt de comando (* tosse * Windows 8 * tosse *) e suponha que não seja muito difícil sobrecarregá-los, mas há definitivamente cenários em que vários aplicativos de console estão em execução e possuem todos e cada um gerar um processo extra, que consome memória e usa PID é horrível, e tentar contorná-lo é, na melhor das hipóteses, terrivelmente inconveniente.
Alguém tem informações definitivas e autorizadas sobre o assunto? Novamente, eu já li a explicação genérica; Estou pensando:
- Por que os aplicativos de console (ainda) devem ser tratados de maneira diferente
- Em que circunstâncias específicas eles precisam ter
conhost
- Quais são as consequências de matar
conhost
- Se existe alguma maneira de parar / impedir / desativar / bloquear ou pelo menos uma maneira fácil de lidar rapidamente com isso posteriormente?
conshost.exe
ainda está gerando?conhost.exe
era o equivalente do Windows a um PTY ecmd.exe
era a concha.Respostas:
Os aplicativos de console devem ser tratados de maneira diferente, porque no kernel do NT (subjacente a 2000, XP, Vista, Windows 7 e Windows 8) eles são cidadãos de segunda classe. Na arquitetura do sistema Unix, todo processo no momento da criação tem os fluxos de entrada, saída e erro padrão anexados; O IO do terminal é implementado em termos desses fluxos (stdin vindo do teclado e stdout / stderr indo para o terminal), e um esforço extra é necessário por parte de um processo que não deseja fazer uso desses fluxos ou ter seus descritores de arquivo são abertos.
Na arquitetura do Windows NT, que embora não seja um descendente linear do VMS foi desenvolvido por mais ou menos a mesma equipe, o oposto é verdadeiro; um processo recém-gerado por padrão não possui fluxos de E / S conectados a ele e não existe um conceito como "terminal". Os programas que desejam se comportar de uma maneira um pouco mais Unixy podem solicitar (por declaração em tempo de compilação) que o sistema crie para eles uma janela do console e os fluxos de entrada / saída conectados a ele; o sistema fará isso, mas como o Windows, diferentemente do Unix, não oferece terminais gratuitamente, é necessário um esforço adicional considerável para criar um, portanto
csrss.exe
, anteriormente e agoraconhost.exe
.Quanto à diferença entre os dois, o seu link "Dificilmente um recurso" explica bastante; em resumo, ele existe para solucionar uma falha de segurança na iteração anterior da API de console altamente recondicionada do Windows, que permitia a escalada de privilégios em versões do NT anteriores ao Windows 7. (Vista, FYI, não possui
conhost.exe
, o que é adequado a status como o Windows Millennium da família NT.)Qualquer programa que queira o equivalente ao Unix stdin / stdout / stderr precisa de um console, daí uma instância de
conhost.exe
. Imigrantes do Unix-land, como Apache, PHP, et al., Vão querer esses fluxos, daí a instanciação automática do sistemaconhost.exe
para eles, se eles realmente exibem uma janela ou não. Em teoria, seria possível modificar a fonte do Apache, por exemplo, de modo que ele não exigisse terminal, e compilá-lo como um aplicativo da GUI do Windows em vez de um aplicativo do console, para que o sistema não sentisse a necessidade de gerá-lo aconhost.exe
. Supondo que também seja possível na prática, ninguém parece ter se importado o suficiente para fazê-lo. Talvez você seja o primeiro.Matar um dado
conhost.exe
quase certamente desabilitará a E / S do console para qualquer processo que esteja sendo executado nessa instância. Você provavelmente não se importa com isso porque está lidando com processos de servidor que não estão fazendo nada de interessante nos fluxos de E / S do console, portanto, provavelmente não há razão para não matar osconhost.exe
s. Em caso de dúvida, mate-os e veja se isso quebra alguma coisa.Não há como impedir o Windows de instanciar
conhost.exe
quando um programa é iniciado que solicita E / S do console; a única maneira de fazer isso seria recompilá-lo para que o Windows não o considere um aplicativo de console. No entanto, supondo que matar o pai de um determinado processo do servidorconhost.exe
não prejudique sua funcionalidade de qualquer maneira que você goste, você poderá matá-los todos de uma vez emitindotaskkill /f /im conhost.exe
um prompt de execução ou uma janela do console - de preferência o primeiro, pois o último provavelmente morrerá e quase certamente deixará de funcionar assim que suaconhost.exe
instância pai for morta. Novamente, em caso de dúvida, mate-os e veja se isso quebra alguma coisa.fonte
All that said, a portable server stack on a Flash drive sounds like it never spends much time running on any given machine
Não sei o que isso significa. Você está falando de ciclos de CPU? Nesse caso, um servidor da Web pode ser bastante criticado se o site for popular o suficiente (e criticado mesmo que não seja; o PHP no Windows não é exatamente barato em termos de CPU). Se você quer dizer com que frequência ele é executado em geral, deixo em execução no meu laptop a semana toda.22M is roughly 1% of the RAM complement of the lowest-end machine you can even easily buy these days. Is it really enough of a problem to be worth this much time and effort?
Você não executa um servidor Web pessoal em uma nova máquina, executa-o em um sistema antigo que não é útil para muitas outras coisas. (Em 1997, um amigo me disse que estava executando um servidor da Web Linux em um sistema antigo e mínimo - segundo os padrões da época). Como é portátil, deve ser o mais compatível possível. E não é apenas a memória ; por um lado, também polui o espaço do processo e desorganiza o Gerenciador de tarefas.Vista, FYI, does not have conhost.exe, which is befitting of its status as the Windows Millennium of the NT family.
É por isso que eu coloquei Vista entrecsrss
aconhost
; foi um passo do meio. Quanto ao pobre Windows ME, não fale mal. Recentemente, reproduzi Jewels of Oracle executando-o no XP no VMPlayer, mas quando tentei jogar Jewels II , não consegui. Não seria executado no XP ou 2000. É executado no 98, mas o 98 possui um suporte de áudio e vídeo ruim no VMPlayer e no VirtualBox. Após uma dúzia de tentativas, descobri que a única combinação de SO e VM que permite que o jogo funcionasse corretamente era ME no VMPlayer.conhost.exe
assim. E quanto ao Windows ME, eu tive que tentar apoiá-lo quando era novo, e você pode citar todos os casos de cantos tardios e obscuros que você gosta, sem abrir mão da minha opinião sobre o café da manhã desse cão em um sistema operacional, que eu poderia falar mal durante todo o dia sem fazer justiça.Um aplicativo de console iniciado com o
DETACHED_PROCESS
sinalizador obtém um console e nem um processo filho. O problema é que o sinalizador não se aplica aos netos; portanto, ele funcionará apenas com os processos iniciados diretamente (se você conseguir encontrar um utilitário que permita especificar esse sinalizador).A outra opção que pode funcionar é se o processo do console chamar a
FreeConsole()
função. Alguns aplicativos de servidor suportam um parâmetro -d ou -detach, mas isso provavelmente é mais comum em sistemas * nix ...fonte
conhost
, mas a conexão parece bastante clara. Vou fazer alguns testes para ver que tipo de efeitos isso tem.Solução rápida que pode funcionar para você. Ao vincular seu aplicativo, adicione / SUBSYSTEM: WINDOWS às opções. Você também pode usar o editbin.exe para modificar um executável existente.
Isso impede que o Windows gere um conhost.exe para seu aplicativo.
fonte
mysqld
, mas quando o executei, ele ainda gerou umaconhost
instância.stderr
ainda é necessário paramysqld
e, portanto, precisaconhost
?