windows - microsoft - procexp64 descargar
¿Cómo destruyo automáticamente procesos secundarios en Windows? (7)
En la aplicación C ++ de Windows, lanzo varios procesos hijos de larga ejecución (actualmente utilizo CreateProcess (...) para hacer esto.
Quiero que los procesos secundarios se cierren automáticamente si mis procesos principales se bloquean o se cierran.
Debido al requisito de que esto debe funcionar para un bloqueo del "padre", creo que esto debería hacerse usando alguna API / característica del sistema operativo. Para que todos los procesos "secundarios" se limpien.
¿Cómo hago esto?
Justo al lado de la parte superior de mi cabeza:
- ¿Ha considerado usar hilos en lugar de procesos?
- Intente pasar el identificador del proceso / subproceso principal a los procesos secundarios y haga que esperen en ese identificador. Esto funciona para subprocesos, ya que la espera en un identificador de subproceso espera hasta que el subproceso finaliza y finaliza. No estoy seguro de si funcionará para los procesos; debería verificar MSDN para verificar esto.
La API de Windows admite objetos llamados "Objetos de trabajo". El siguiente código creará un "trabajo" que está configurado para cerrar todos los procesos cuando finaliza la aplicación principal (cuando se limpian sus identificadores). Este código solo debe ejecutarse una vez .:
HANDLE ghJob = CreateJobObject( NULL, NULL); // GLOBAL
if( ghJob == NULL)
{
::MessageBox( 0, "Could not create job object", "TEST", MB_OK);
}
else
{
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
// Configure all child processes associated with the job to terminate when the
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if( 0 == SetInformationJobObject( ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
{
::MessageBox( 0, "Could not SetInformationJobObject", "TEST", MB_OK);
}
}
Luego, cuando se crea cada proceso secundario, ejecute el siguiente código para iniciar cada elemento secundario de cada proceso y agregarlo al objeto de trabajo:
STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;
// Launch child process - example is notepad.exe
if (::CreateProcess( NULL, "notepad.exe", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
::MessageBox( 0, "CreateProcess succeeded.", "TEST", MB_OK);
if(ghJob)
{
if(0 == AssignProcessToJobObject( ghJob, processInfo.hProcess))
{
::MessageBox( 0, "Could not AssignProcessToObject", "TEST", MB_OK);
}
}
// Can we free handles now? Not sure about this.
//CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
NOTA DE VISTA: vea AssignProcessToJobObject siempre devuelva "acceso denegado" en Vista si encuentra problemas de acceso denegado con AssignProcessToObject () en vista.
Objetos de trabajo de Windows parece un buen lugar para comenzar. El nombre del objeto de trabajo debería ser conocido o transferido a los hijos (o heredar el identificador). Los niños necesitarían ser notificados cuando el padre muera, ya sea a través de un "latido" del IPC fallido o simplemente WFMO / WFSO en el manejo del proceso de los padres. En ese punto, cualquier proceso secundario podría TermianteJobObject para derribar a todo el grupo.
Podría encapsular cada proceso en un objeto C ++ y mantener una lista de ellos en alcance global. Los destructores pueden cerrar cada proceso. Eso funcionará bien si el programa sale normalmente pero se bloquea, todas las apuestas están apagadas.
Aquí hay un ejemplo aproximado:
class myprocess
{
public:
myprocess(HANDLE hProcess)
: _hProcess(hProcess)
{ }
~myprocess()
{
TerminateProcess(_hProcess, 0);
}
private:
HANDLE _hProcess;
};
std::list<myprocess> allprocesses;
Luego, cada vez que inicie uno, llame a allprocessess.push_back (hProcess);
Probablemente tengas que mantener una lista de los procesos que inicias y matarlos uno por uno cuando salgas de tu programa. No estoy seguro de los detalles de hacer esto en C ++, pero no debería ser difícil. La parte difícil probablemente sea asegurar que los procesos secundarios se cierren en caso de una falla de la aplicación. .Net tiene la capacidad de agregar una función que recibe cuando se produce una excepción no controlada. No estoy seguro si C ++ ofrece las mismas capacidades.
Puede mantener un proceso de vigilancia independiente ejecutándose. Su única tarea es observar el espacio de proceso actual para detectar situaciones como las que describes. Incluso podría relanzar la aplicación original después de un bloqueo o proporcionar diferentes opciones al usuario, recopilar información sobre depuración, etc. Simplemente trate de mantenerlo lo suficientemente simple para que no necesite un segundo perro guardián para ver el primero.
Una solución algo hackosa sería que el proceso principal se adjunte a cada hijo como un depurador (use DebugActiveProcess ). Cuando un depurador finaliza, todos sus procesos de depuración finalizan también.
Una mejor solución (suponiendo que también hayas escrito los procesos secundarios) sería hacer que los procesos secundarios supervisen a los padres y salir si desaparecen.