c ++ fork,无需等待,解散execl

时间:2012-02-06 17:25:34

标签: c++

想要在c ++中分叉一个不会挂起其父进程的进程 - 它的父进程是守护进程,必须保持运行。如果我在分叉进程上等待(),分叉的execl将不会解除 - 但是 - 它也会挂起应用程序 - 而不是等待修复应用程序挂起 - 但命令变得无法解决。

if((pid = fork()) < 0)
    perror("Error with Fork()");
else if(pid > 0) { 
    //wait here will hang the execl in the parent
    //dont wait will defunt the execl command 
    //---- wait(&pid);
    return "";
} else {
    struct rlimit       rl;
    int                 i;

    if (rl.rlim_max == RLIM_INFINITY)
        rl.rlim_max = 1024;

    for (i = 0; (unsigned) i < rl.rlim_max; i++)
        close(i);

    if(execl("/bin/bash", "/bin/bash", "-c", "whoami", (char*) 0) < 0) perror("execl()");
    exit(0);
}

如果没有等待(&amp; pid)execl的命令不会解散,我怎么能分叉execl?

更新 修正了在fork之前添加以下内容

signal(SIGCHLD, SIG_IGN);

仍然根据我接受的答案,在更兼容的解决方案中使用我有限的技能。谢谢!

3 个答案:

答案 0 :(得分:6)

默认情况下,wait和朋友会等到进程退出,然后重新获取。如果没有孩子退出,您可以使用waitpid致电WNOHANG立即返回。

已解散/“僵尸”进程将一直存在,直到你wait为止。因此,如果您在后台运行它,您必须安排最终通过以下几种方式获取它:

  • 定期waitpid WNOHANG int pid = waitpid(-1, &status, WNOHANG) SIGCHLDsigaction
  • 安装SA_NOCLDWAIT的信号处理程序,以便在退出时收到通知

此外,在POSIX.1-2001下,您可以使用SIGCHLDSIG_IGN上设置SA_NOCLDWAIT。或者将其操作设置为{{1}}。较旧的系统(包括Linux 2.4.x,但不包括2.6.x或3.x)不支持此功能。

检查系统联机帮助页,或替代wait in the Single Unix Specification。 Single Unix Spec还提供了一些有用的代码示例。 sigaction中记录了{{1}}。

答案 1 :(得分:0)

我认为信号处理程序将是指示的最佳方式。我想指出另一种可以处理的方法:fork两次并让子进出,而孙子会调用execl。然后,init过程将清除已失效的进程。

答案 2 :(得分:0)

如评论中所述,双叉可将进程从失效状态中保存下来。

What is the reason for performing a double fork when creating a daemon?