Fondo
El año pasado compilé un sistema portátil de blog / servidor web que puedo ejecutar desde una unidad flash. Es genial y funciona de maravilla, especialmente en XP. El problema es que cuando se ejecuta en Windows 7, cada programa de consola genera dos procesos, el proceso en sí mismo, más una copia de conhost.exe
.
Problema
En el caso del sistema de blog portátil, cada uno de sus componentes de servidor (MySQL mysqld.exe
, dos instancias de Apache, dos instancias de httpd.exe
VisualSVN visualsvnserver.exe
y múltiples instancias de PHP php-cgi.exe
) genera una instancia de conhost.exe
. En este momento (sin copias de php-cgi.exe
activo, tengo cinco instancias de conhost.exe
ejecución, usando casi ningún ciclo de CPU, pero consumiendo 22 MB de memoria (además de los 80 MB que los procesos reales están usando actualmente).
Investigación
Desde que se lanzó Windows 7 (y creo que posiblemente desde Vista), tengo en varias ocasiones trató de averiguar exactamente qué propósito los diferentes procesos (nuevo) huésped (por ejemplo, conhost.exe
, dllhost.exe
, y taskhost.exe
) hacer y si son realmente necesarias. Intenté matarlos y descubrí que los programas de consola continúan funcionando, tanto para los programas que usan una ventana de consola como para los que no (como los servidores).
Ya estoy familiarizado con todo el csrss.exe
⇨ Windows Vista ⇨conhost.exe
y he visto esa misma explicación (casi textualmente) en numerosas ocasiones. El problema es que todos simplemente copian y pegan la misma explicación que no es útil. Todo lo que dice es que en XP-, las aplicaciones de consola csrss.exe
estaban "alojadas por" o "se ejecutaban bajo" , pero en Windows 7, se trasladaron a ellas conhost.exe
por seguridad. El aspecto de seguridad tiene sentido, pero no dice nada sobre lo que significa alojarlo o por qué / cuándo es necesario (o si es posible evitarlo si no es necesario). Incluso la discusión de Raymond Chen sobre el tema pasa por alto por qué las aplicaciones de consola están alojadas de manera diferente.
Lo más parecido que puedo encontrar a una explicación técnica detallada es una publicación de blog de Microsoft que parece reforzar la idea de que se trata simplemente de la ventana y la GUI de la aplicación de consola. Esto me hace preguntarme aún más si conhost.exe
es necesario para programas sin ventanas como estos servidores. Si no hay ninguna ventana, ¿por qué debería tener que desperdiciar recursos y desordenar el espacio de procesos con procesos innecesarios? ¿Por qué Windows no puede detectar cuando es innecesario y evitarlo? La respuesta de SecurityMatt también fue un poco útil en lo que respecta a una explicación técnica, pero nuevamente, no es suficiente la información que estoy buscando.
No soy el único que ha tratado de encontrar una manera de detener instancias innecesarias conhost
. Esta persona preguntó acerca de deshabilitarlo y se le dijo simplemente "no es posible" sin más esfuerzo o pensamiento al respecto. Hugh D y "Hardly a feature" señalaron el problema con numerosas instancias redundantes de conhost
(al menos csrss
, solo se estaba ejecutando una copia), incluido el uso de recursos y las instancias persistentes después de que sus procesos secundarios hayan finalizado. Laufer cuestionó si / cuándo es necesario.
Observaciones e intentos de solución
Si no son realmente necesarios en todo momento (una vez más, no he visto ningún efecto negativo por matarlos), entonces supongo que podría (muy irritantemente) solucionar el problema reemplazando los servidores con archivos por lotes que los ejecutan. , espere y luego elimine la copia conhost
que causan que se ejecute. Por supuesto, esto requiere una forma rápida y fácil de determinar cuál es. FallenGameR preguntó cómo obtener la instancia de conhost.exe
asociado con un programa de consola de un PID determinado, pero no obtuvo una respuesta. Creo que simplemente recuperar el PID del proceso principal debería ser el truco (no, ProcessExplorer no es una opción, un automatizado / programablese requiere una solución), pero eso no solo requeriría crear algún tipo de marco para obtener el PID del niño (en lugar de simplemente ejecutarlo y terminar con la tarea), sino que también significaría encontrar una manera de hacerlo compatible con XP también (por ejemplo, verificando el nombre de la imagen del proceso padre). Esta publicación de blog ofrece una forma, pero requiere PowerShell y no es ideal, sin mencionar que no dice nada sobre las ramificaciones de ejecutar el script.
Pregunta (s)
Quizás Microsoft se da cuenta de que ya nadie usa las instrucciones de comando (* tos * Windows 8 * tos *) y, por lo tanto, asumió que no es un gran problema cargarlos, pero definitivamente hay escenarios en los que se ejecutan varias aplicaciones de consola y tienen todas y cada una generar un proceso adicional, que consume memoria y usa PID es horrible, y tratar de solucionarlo es, en el mejor de los casos, terriblemente inconveniente.
¿Alguien tiene información definitiva y autorizada sobre el asunto? Nuevamente, ya leí la explicación genérica; Me pregunto:
- ¿Por qué las aplicaciones de consola deben (todavía) manejarse de manera diferente?
- Bajo qué circunstancias específicas necesitan tener
conhost
- Cuáles son las consecuencias de matar
conhost
- ¿Si hay alguna forma de detenerlo / prevenirlo / deshabilitarlo / bloquearlo o al menos una manera fácil de tratarlo rápidamente después?
conshost.exe
sigue apareciendo?conhost.exe
era el equivalente de Windows de un PTY, y quecmd.exe
era el shell.Respuestas:
Las aplicaciones de consola deben manejarse de manera diferente porque bajo el kernel NT (que subyace a todo 2000, XP, Vista, Windows 7 y Windows 8) son ciudadanos de segunda clase. En la arquitectura del sistema Unix, cada proceso en el momento de la creación tiene las secuencias de entrada, salida y error estándar adjuntas; el terminal IO se implementa en términos de estas secuencias (stdin que proviene del teclado y stdout / stderr que va a la terminal), y se requiere un esfuerzo adicional por parte de un proceso que no desea hacer uso de esas secuencias o tener se abren sus descriptores de archivo.
En la arquitectura de Windows NT, que si bien no es un descendiente lineal de VMS desarrollado por más o menos el mismo equipo, lo contrario es cierto; un proceso recién generado por defecto no tiene corrientes de E / S conectadas a él, y no existe el concepto de "terminal". Los programas que desean comportarse de una manera un poco más Unixy pueden solicitar (por declaración de tiempo de compilación) que el sistema les cree una ventana de consola y flujos de entrada / salida conectados a ella; el sistema lo hará, pero dado que Windows, a diferencia de Unix, no le da terminales de forma gratuita, se requiere una cantidad considerable de esfuerzo adicional para crear uno, por lo tanto
csrss.exe
, antes y ahoraconhost.exe
.En cuanto a la diferencia entre los dos, su enlace "Apenas una característica" lo explica de manera bastante adecuada; en resumen, existe para evitar una falla de seguridad en la iteración anterior de la API de consola altamente recóndita de Windows, que permitió la escalada de privilegios en versiones de NT anteriores a Windows 7. (Vista, FYI, no tiene
conhost.exe
, lo cual es apropiado para su estado como Windows Millennium de la familia NT).Cualquier programa que quiera el equivalente de Unix stdin / stdout / stderr necesita una consola, de ahí una instancia de
conhost.exe
. Los inmigrantes de Unix-land, como Apache, PHP, et al., Van a querer estos flujos, de ahí la creación de instancias automáticas del sistemaconhost.exe
para ellos, ya sea que realmente muestren una ventana o no. En teoría, sería posible modificar la fuente para, por ejemplo, Apache, de modo que no requiriera terminal, y compilarlo como una aplicación GUI de Windows en lugar de una aplicación de consola, para que el sistema no sintiera la necesidad de generarloconhost.exe
. Asumiendo que también es posible en la práctica, nadie parece haberse preocupado lo suficiente como para hacerlo. Quizás seas el primero.Matar a un dado
conhost.exe
seguramente deshabilitará la consola IO para cualquier proceso que se ejecute en esa instancia. Probablemente no le importe eso porque está lidiando con procesos de servidor que no están haciendo nada interesante en las transmisiones de E / S de la consola de todos modos, por lo que probablemente no haya razón para no matar sus correos electrónicosconhost.exe
. En caso de duda, mátalos y ve si se rompe algo.No hay forma de evitar que Windows cree instancias
conhost.exe
cuando se inicia un programa que solicita la consola IO; la única forma de hacerlo sería recompilarlo para que Windows no lo considere como una aplicación de consola. Sin embargo, suponiendo que matar a un padre del proceso de un servidor dadoconhost.exe
no perjudique su funcionalidad de ninguna manera que le interese, debería poder matarlos a todos al mismo tiempo emitiendotaskkill /f /im conhost.exe
un mensaje Ejecutar o una ventana de consola, preferiblemente la primera, ya que este último probablemente morirá, y casi seguramente dejará de funcionar, tan pronto como se elimine suconhost.exe
instancia principal . De nuevo, en caso de duda, mátalos y ve si se rompe algo.fuente
All that said, a portable server stack on a Flash drive sounds like it never spends much time running on any given machine
No sé lo que esto significa. ¿Estás hablando de ciclos de CPU? Si es así, un servidor web puede verse afectado si el sitio es lo suficientemente popular (e incluso si no lo es; PHP en Windows no es exactamente barato para la CPU). Si quiere decir con qué frecuencia se ejecuta en general, lo dejo ejecutándose en mi computadora portátil durante toda la semana.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?
No ejecuta un servidor web personal en una nueva máquina, lo ejecuta en un sistema antiguo que no es útil para mucho más. (En 1997, un amigo me dijo que estaba ejecutando un servidor web Linux en un sistema antiguo y mínimo, según el estándar de esa época). Dado que es portátil, debe ser lo más compatible posible. Y no es solo el recuerdo ; Por un lado, también contamina el espacio de proceso y desordena el Administrador de tareas.Vista, FYI, does not have conhost.exe, which is befitting of its status as the Windows Millennium of the NT family.
Es por eso que pongo entre Vistacsrss
aconhost
; Fue un paso intermedio. En cuanto al pobre Windows ME, no lo hable mal. Recientemente volví a jugar Jewels of the Oracle ejecutándolo en XP en VMPlayer, pero cuando intenté jugar Jewels II , no pude. No se ejecutaría en XP o 2000. Se ejecuta en 98, pero 98 tiene poca compatibilidad de audio y video en VMPlayer y VirtualBox. Después de una docena de intentos, descubrí que la única combinación de SO y VM que permite que el juego funcione correctamente era ME en VMPlayer.conhost.exe
esa manera. Y en cuanto a Windows ME, tuve que tratar de respaldarlo cuando era nuevo, y puedes citar todos los casos de esquina oscuros y tardíos que te gustan sin cambiar mi opinión sobre el desayuno de ese perro de un sistema operativo, que podría hablar mal todo el día sin hacerle justicia.Una aplicación de consola iniciada con el
DETACHED_PROCESS
indicador no obtiene una consola ni un proceso secundario conhost. El problema es que el indicador no se aplica a los nietos, por lo que solo funcionará con los procesos que inicie directamente (si incluso puede encontrar una utilidad que le permita especificar este indicador).La otra opción que podría funcionar es si el proceso de la consola llama a la
FreeConsole()
función. Algunas aplicaciones de servidor admiten un parámetro -d o -detach, pero esto es probablemente más común en los sistemas * nix ...fuente
conhost
, pero la conexión parece bastante clara. Haré algunas pruebas para ver qué tipo de efectos tiene.Solución rápida que puede funcionar para usted. Al vincular su aplicación, agregue / SUBSYSTEM: WINDOWS a las opciones. También podría usar editbin.exe para modificar un ejecutable existente.
Esto evita que Windows genere un conhost.exe para su aplicación.
fuente
mysqld
, pero cuando lo ejecuté, todavía generó unaconhost
instancia.stderr
todavía se necesitamysqld
y, por lo tanto, necesitaconhost
?