在C++ Windows应用程序中,我启动了几个长时间运行的子进程(目前我使用CreateProcess(...)要做到这一点。
如果我的主进程崩溃或被关闭,我希望子进程自动关闭。
因为这需要解决“父进程”崩溃的问题,所以我认为这需要使用操作系统的一些API/功能来完成。这样所有的“子”进程都会被清理掉。
我该怎么做呢?
发布于 2008-09-10 00:22:50
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 always return "access denied" on Vista。
发布于 2008-09-10 00:28:14
一种有点老套的解决方案是让父进程作为调试器附加到每个子进程(使用DebugActiveProcess。当调试器终止时,它的所有被调试进程也将终止。
一个更好的解决方案(假设您也写了子进程)是使子进程监视父进程,如果父进程消失,则退出。
发布于 2008-09-10 06:24:55
Windows作业对象听起来像是一个很好的起点。Job对象的名称必须是众所周知的,或者传递给子对象(或者继承句柄)。当父进程终止时,需要通知子进程,无论是通过失败的IPC“心跳”还是在父进程句柄上的WFMO/WFSO。在这一点上,任何子进程都可以通过TermianteJobObject来拖垮整个组。
https://stackoverflow.com/questions/53208
复制相似问题