关于进程:如何在Windows中自动销毁子进程?

关于进程:如何在Windows中自动销毁子进程?

How do I automatically destroy child processes in Windows?

在C ++ Windows应用程序中,我启动了几个长时间运行的子进程(当前我使用CreateProcess(...)来执行此操作。

如果主进程崩溃或关闭,我希望子进程自动关闭。

由于需要在"父"崩溃时起作用,因此我认为这需要使用操作系统的某些API /功能来完成。 这样就清除了所有"子"过程。

我该怎么做呢?


Windows API支持称为"作业对象"的对象。以下代码将创建一个"作业",该作业被配置为在主应用程序结束时(清理其句柄时)关闭所有进程。该代码只能运行一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);
    }
}

然后,在创建每个子进程时,执行以下代码以启动每个子进程并将其添加到作业对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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()的访问被拒绝的问题,请参阅Vista上的AssignProcessToJobObject始终返回"拒绝访问"。


一个有点棘手的解决方案是将父进程作为调试器附加到每个子进程(使用DebugActiveProcess)。当调试器终止时,其所有调试进程也将终止。

更好的解决方案(假设您也编写了子进程)是让子进程监视父进程,并在父进程消失时退出。


Windows Job Objects听起来是一个不错的起点。 Job Object的名称必须是众所周知的,或传递给子代(或继承该句柄)。当家长死亡时,需要通过失败的IPC"心跳"或仅在家长的进程句柄上的WFMO / WFSO来通知孩子。届时,任何子进程都可以使用TermianteJobObject降低整个组的工作效率。


您可以保持单独的监视程序运行。它的唯一任务是观察当前的过程空间以发现您所描述的情况。它甚至可以在崩溃后重新启动原始应用程序,或向用户提供不同的选项,收集调试信息等。只需尝试使其足够简单即可,您就不需要第二个看门狗来监视第一个。


您可以将每个进程封装在C ++对象中,并在全局范围内保留它们的列表。析构函数可以关闭每个进程。如果程序正常退出但崩溃了,那么所有的赌注都关闭了,这样就可以正常工作。

这是一个粗略的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class myprocess
{
public:
    myprocess(HANDLE hProcess)
        : _hProcess(hProcess)
    { }

    ~myprocess()
    {
        TerminateProcess(_hProcess, 0);
    }

private:
    HANDLE _hProcess;
};

std::list<myprocess> allprocesses;

然后,每当启动一个时,调用allprocessess.push_back(hProcess);。


您可能必须保留启动进程的列表,并在退出程序时将其一一杀死。我不确定在C ++中执行此操作的具体细节,但这并不难。困难的部分可能是确保在应用程序崩溃时关闭子进程。 .Net能够添加一个功能,该功能在发生未处理的异常时被调用。我不确定C ++是否提供相同的功能。


就在我的头顶上:

  • 您是否考虑过使用线程而不是进程?
  • 尝试将主线程/?痰木浔莞咏蹋⑹顾窃诟镁浔系却U馐视糜谙叱蹋蛭却叱叹浔恢钡鹊礁孟叱掏瓿刹⑼顺觥2惶范ㄋ欠袷视糜诮蹋η┏鯩SDN进行验证。

推荐阅读

    linux运行vim命令?

    linux运行vim命令?,系统,工具,官方网站,模式,基础,数据,代码,环境,入口,命令

    linux下看进程命令行?

    linux下看进程命令行?,系统,情况,软件,服务,状态,名称,环境,进程,命令,数据,

    linux监控命令运行?

    linux监控命令运行?,系统,工作,地址,信息,工具,情况,标准,环境,命令,状态,lin

    linux进程与磁盘命令?

    linux进程与磁盘命令?,管理,系统,信息,情况,基础,增长,单位,地址,发行,命令,L

    linux的进程管理命令?

    linux的进程管理命令?,系统,实时,工作,管理,命令,地址,名称,进程,服务,基础,l

    linux端口进程命令?

    linux端口进程命令?,系统,情况,地址,网络,信息,状态,灵活,工具,端口,命令,如

    linux自动运行命令?

    linux自动运行命令?,服务,系统,时间,代码,周期性,第一,命令,管理,在线,状态,l

    linux进程的命令行?

    linux进程的命令行?,地址,工作,系统,信息,命令,管理,名称,进程,目录,服务,lin

    linux开启运行命令?

    linux开启运行命令?,系统,服务,工作,管理,状态,命令,标准,情况,环境,工具,lin

    linux运行wps命令?

    linux运行wps命令?,软件,官网,名称,时间,电脑,系统,工具,环境,项目,数据,wps

    linux当前进程命令?

    linux当前进程命令?,系统,信息,工作,状态,命令,进程,情况,地址,软件,实时,lin

    linux运行cmd命令?

    linux运行cmd命令?,电脑,系统,状态,情况,环境,命令,单位,管理,设备,数据,电脑

    linux运行两个命令?

    linux运行两个命令?,网络,地址,系统,工作,暂停,命令,网站,密码,网上,入口,Lin

    linux下杀进程命令?

    linux下杀进程命令?,系统,管理,进程,命令,名称,代码,终端,结束,指令,信号,Lin

    linux关于的进程命令?

    linux关于的进程命令?,系统,进程,管理,命令,名称,代码,软件,信息,定期,状态,l

    linux命令运行代码?

    linux命令运行代码?,代码,单位,系统,环境,连续,保险,工具,命令,文件,音乐,Lin

    linux终止进程命令键?

    linux终止进程命令键?,系统,管理,进程,软件,暂停,工具,命令,代码,名称,传播,l

    linux命令运行脚本?

    linux命令运行脚本?,代码,系统,工作,设计,状态,命令,脚本,文件,目录,终端,运

    linux向进程发送命令?

    linux向进程发送命令?,通信,地址,系统,时间,工作,信息,管理,状态,进程,数据,l

    linux上运行的命令?

    linux上运行的命令?,系统,工作,软件,网络,地址,信息,情况,命令,灵活,基础知