Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I automatically destroy child processes in Windows?

In C++ Windows app, I launch several long running child processes (currently I use CreateProcess(...) to do this.

I want the child processes to be automatically closed if my main processes crashes or is closed.

Because of the requirement that this needs to work for a crash of the "parent", I believe this would need to be done using some API/feature of the operating system. So that all the "child" processes are cleaned up.

How do I do this?

like image 748
jm. Avatar asked Sep 10 '08 00:09

jm.


People also ask

How do I kill a child process in Windows?

The solution is to use "job objects" http://msdn.microsoft.com/en-us/library/ms682409(VS.85).aspx. The idea is to create a "job object" for your main application, and register your child processes with the job object. If the main process dies, the OS will take care of terminating the child processes.

How can we stop child processes?

For killing a child process after a given timeout, we can use the timeout command. It runs the command passed to it and kills it with the SIGTERM signal after the given timeout. In case we want to send a different signal like SIGINT to the process, we can use the –signal flag.

What happens to child process when parent is killed Windows?

In chrome on Windows, the child processes are in a job object and so the OS takes care of killing them when the parent process dies.

Can a process have multiple child processes?

Creating multiple process using fork() Explanation – Here, we had used fork() function to create four processes one Parent and three child processes. An existing process can create a new one by calling the fork( ) function. The new process created by fork() is called the child process.


2 Answers

The Windows API supports objects called "Job Objects". The following code will create a "job" that is configured to shut down all processes when the main application ends (when its handles are cleaned up). This code should only be run once.:

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);     } } 

Then when each child process is created, execute the following code to launch each child each process and add it to the job object:

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); } 

VISTA NOTE: See AssignProcessToJobObject always return "access denied" on Vista if you encounter access-denied issues with AssignProcessToObject() on vista.

like image 119
jm. Avatar answered Sep 26 '22 12:09

jm.


One somewhat hackish solution would be for the parent process to attach to each child as a debugger (use DebugActiveProcess). When a debugger terminates all its debuggee processes are terminated as well.

A better solution (assuming you wrote the child processes as well) would be to have the child processes monitor the parent and exit if it goes away.

like image 33
Rob Walker Avatar answered Sep 25 '22 12:09

Rob Walker