c++ - 如何生成不与父进程一起死亡的子进程?

标签 c++ linux fork parent-child spawn

我有一个 C++ 程序可以充当其他程序的看门狗。如果它检测到一个进程不再运行,它会通过 system 重新启动它。问题是,如果我杀死看门狗进程,它启动的任何进程也会死亡。

void* ProcessWatchdog::worker(void* arg)
{
    //Check if process is running
    if( !processRunning )
        system("processName /path/to/processConfig.xml &");
}

新的子进程正确启动,运行没有任何问题。但是,当父进程(现在是 ProcessWatchdog 进程)死亡时,子进程也会死亡。如何生成完全独立于父进程的子进程?

我试过使用 pclosepopen,运行启动进程的 shell 脚本,以及其他一些策略,但都无济于事。我忽略了子进程中的 SIGHUP 信号,但它们仍然死掉了。

理想情况下,我想告诉系统启动一个完全独立于父进程的进程。我希望 child 的 trace 以 child 结束,并且它/系统不知道 ProcessWatchdog 一开始就启动了它。

我有办法做到这一点吗?

我在 Linux 上用 C++ 编写。

最佳答案

这个有点旧,但没有得到完整的答案。这是我在嵌入式系统上所做的,以生成一个与父级无关的 bash 子级。请注意,我执行了一个 bash shell,然后在另一个 bash shell 中运行我的命令。这在您的情况下可能没有必要。对我来说,它允许我进行一些 I/O 重定向,没有它就无法正常工作。

两个重要的概念是setsid() 和double fork()。这两者的结合可以防止在孤儿完成时创建僵尸,并防止在父级完成时杀死孤儿。

还有许多其他问题可能会出现,例如继承的 I/O 句柄、工作目录等,但这段代码完成了基本工作。

int spawn_orphan(char* cmd) {
    char command[1024]; // We could segfault if cmd is longer than 1000 bytes or so
    int pid;
    int Stat;
    pid = fork();
    if (pid < 0) { perror("FORK FAILED\n"); return pid; }
    if (pid == 0) { // CHILD
        setsid(); // Make this process the session leader of a new session
        pid = fork();
        if (pid < 0) { printf("FORK FAILED\n"); exit(1); }
        if (pid == 0) { // GRANDCHILD
            sprintf(command,"bash -c '%s'",cmd);
            execl("/bin/bash", "bash", "-c", command, NULL); // Only returns on error
            perror("execl failed");
            exit(1);
        }
        exit(0); // SUCCESS (This child is reaped below with waitpid())
    }

    // Reap the child, leaving the grandchild to be inherited by init
    waitpid(pid, &Stat, 0);
    if ( WIFEXITED(Stat) && (WEXITSTATUS(Stat) == 0) ) {
        return 0; // Child forked and exited successfully
    }
    else {
        perror("failed to spawn orphan\n");
        return -1;
    }
}

关于c++ - 如何生成不与父进程一起死亡的子进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17599096/

相关文章:

c++ - 为什么方法不起作用?

linux - 如何安装特定版本的ImageMagick头文件?

linux - 警告 libstdc++-devel-4.4.4-13.el6.x86_64.rpm

c - fork + wait 在 OSX 上获取 EINTR

google-analytics - 在 Google Analytics 上使用多个自定义变量

c++ - 使用 symstore.exe 无法在 Windbg 或 Visual Studio 中为小型转储加载符号

c++ - 使用 RANSAC 估计两组点之间的二维变换

python - 使用超线程运行模拟使运行时间加倍

c - 为 pthread 分配内存,然后 fork + execvp

c++ - IBM WebSphere MQ 在 Windows 上支持 64 位客户端吗?