在C++ Windows应用程序中,我启动了几个长时间运行的子进程(目前我使用CreateProcess(...)来执行此操作.
如果我的主进程崩溃或关闭,我希望子进程自动关闭.
由于要求这需要对"父"的崩溃起作用,我认为这需要使用操作系统的某些API /功能来完成.这样就可以清理所有"子"进程.
我该怎么做呢?
Windows API支持名为"作业对象"的对象.以下代码将创建一个"作业",配置为在主应用程序结束时(清除其句柄时)关闭所有进程.此代码只能运行一次:
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);
}
}
然后,当创建每个子进程时,执行以下代码以启动每个进程的每个进程并将其添加到作业对象:
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注意:如果在Vista上遇到与AssignProcessToObject()的访问被拒绝问题,请参阅AssignProcessToJobObject始终在Vista上返回"访问被拒绝".
一个有点hackish解决方案是父进程作为调试器附加到每个子进程(使用DebugActiveProcess).当调试器终止时,它的所有调试对象进程也会终止.
一个更好的解决方案(假设您也编写了子进程)将让子进程监视父进程并在它消失时退出.