zac*_*618 6 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 &");
}
Run Code Online (Sandbox Code Playgroud)
新的子进程正确启动,并且运行没有任何问题.但是当父母(现在这个ProcessWatchdog过程)死亡时,孩子也会死亡.如何生成完全独立于父级的子进程?
我已经尝试过使用pclose和popen运行启动进程的shell脚本,以及其他一些策略,但无济于事.我忽略SIGHUP了子进程中的信号,但它们仍然死亡.
理想情况下,我想告诉系统启动一个完全独立于父级的进程.我希望孩子trace以孩子结束,因为它/系统不知道从一ProcessWatchdog开始就开始了它.
有没有办法可以做到这一点?
我在Linux上用C++编写这个.
这个有点旧,但没有得到完整的答案。这是我在嵌入式系统上所做的,以生成与父级无关的 bash 子级。请注意,我执行了一个 bash shell,然后在另一个 bash shell 中运行我的命令。在您的情况下,这可能不是必需的。对我来说,它允许我做一些没有它就不能正常工作的 I/O 重定向。
两个重要的概念是setsid() 和双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;
}
}
Run Code Online (Sandbox Code Playgroud)
尝试在进程名称之前使用systemwith 。setsid
system("setsid processname /path/to/processConfig.xml &");
Run Code Online (Sandbox Code Playgroud)
这将在新会话中启动该程序。