我有一个 C++ 程序可以充当其他程序的看门狗。如果它检测到一个进程不再运行,它会通过 system
重新启动它。问题是,如果我杀死看门狗进程,它启动的任何进程也会死亡。
void* ProcessWatchdog::worker(void* arg)
{
//Check if process is running
if( !processRunning )
system("processName /path/to/processConfig.xml &");
}
新的子进程正确启动,运行没有任何问题。但是,当父进程(现在是 ProcessWatchdog
进程)死亡时,子进程也会死亡。如何生成完全独立于父进程的子进程?
我试过使用 pclose
和 popen
,运行启动进程的 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/