【问题标题】:How do I exec() a process in the background in C?如何在 C 的后台执行()进程?
【发布时间】:2010-12-09 18:41:03
【问题描述】:

我已经对一个进程执行了 fork 和 exec(),但我想在后台运行它。我怎样才能做到这一点? 我可以避免在其上调用 waitpid,但随后该进程将永远坐在那里,等待将其状态返回给父级。有没有其他方法可以做到这一点?

【问题讨论】:

    标签: c process exec


    【解决方案1】:

    捕获 SIGCHLD 并在处理程序中调用 wait()。

    Posix 的一些风格(我认为是 *BSD,但不要引用我的话),如果你忽略 SIGCHLD,内核将自动清理僵尸进程(这是你在 ps 中看到的)。这是一个不错的功能,但不便于携带。

    【讨论】:

    • 这是实施的最干净的解决方案。谢谢!
    • 对于未来有同样问题的程序员,这是我在“UNIX 环境中的高级编程”的第 293 页上找到的内容: SIGCHLD 每当进程终止或停止时,SIGCHLD 信号就会发送给父进程。默认情况下,此信号被忽略,因此如果父母想要在孩子的状态发生变化时收到通知,则必须捕获此信号。信号捕获函数中的正常动作是调用其中一个等待函数来获取子进程 ID 和终止状态。在这种情况下,我只需要像 liw.fi 这样的行建议:waitpid(-1,&status,WNOHANG | WUNTRACED);
    【解决方案2】:

    我认为您正在尝试做的是创建一个守护进程。阅读维基百科上的this 链接以获得解释。

    使进程成为守护进程的示例(来自 Steven 的 Unix 环境中的高级编程)是:

    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h> 
    
    int daemon_int(void)
    {
        pid_t pid;
        if ((pid = fork()) < 0)
            return (-1) ;
        else if (pid != 0)
           exit(0) ; /* The parent process exits */
        setsid() ;   /* become session leader */
        chdir("/") ; /* change the working dir */
        umask(0) ;   /* clear out the file mode creation mask */
        return(0) ;
    }
    

    当然,这假设是一个类似 Unix 的操作系统。

    所以你的程序包含了上述函数,并在运行后立即调用它。然后它会与它的父进程解除关联,并继续运行,直到它终止或被杀死。

    【讨论】:

    • 嗯,仔细阅读这个问题让我觉得 Avi 可能有答案。或者您可以使第一个孩子成为等待孙子终止的守护进程。所以你打破了父母和孩子之间的联系,这样父母就可以在不导致孩子和孙子退出的情况下终止。
    • 如果你想这样做,你还希望你的原始进程调用 wait() 来获取它的子进程。由于子进程将快速退出(在 fork 孙子进程后立即退出),因此您的原始进程不会在 wait() 中长时间阻塞。
    【解决方案3】:

    waitpid(-1, &amp;status, WNOHANG) 可能会做您需要的事情:如果没有子进程退出,它应该立即返回。或者,您可以监听 SIGCHLD 信号。

    【讨论】:

    • 这不是一个好策略 - 除非父进程准备好一遍又一遍地这样做(否则你仍然会遇到僵尸)。
    • 不幸的是,我得到了 Martin 预测的结果,但在那之前听起来确实不错。
    • 这一切都取决于父进程的结构。有时,偶尔轮询比捕获 SIGCHLD 更容易。
    【解决方案4】:

    fork 创建后台线程,然后执行。在这个网站上看到一个欺骗问题:Can we start a background process using exec() giving & as an argument?

    【讨论】:

    • 是的,我看到了这个问题,但它仍然没有回答我原来的问题。当然,我可以避免等待电话,但随后该过程将永远存在。每次运行 ps -al 都能看到。
    • 我认为过去问题的答案实际上并没有回答这个问题(正如 aditya 也抱怨的那样); Avi给出了正确答案。此外,我怀疑过去问题的答案是否确实回答了过去的问题(因为 OP 还想创建一个后台进程,没有人告诉他关于双叉)。
    猜你喜欢
    • 2015-01-18
    • 1970-01-01
    • 2010-09-07
    • 2023-03-29
    • 2018-08-05
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    相关资源
    最近更新 更多