失败/退出时监视并重新启动子进程

时间:2014-03-05 00:25:46

标签: c unix process fork waitpid

我创建了一个监视子进程并在失败或退出时重新启动它的基本示例。这样做的首选/更强大的方法是什么?持续调查状态变化是一种好习惯吗?我的理解是我应该利用像SIGCHLD这样的东西,但却找不到任何好的例子。

我主要是嵌入式C编码器,这是我尝试理解fork()的第一次尝试。此代码的目的最终是使用exec()监视对另一个程序的调用并重启这个程序是否失败或完成。

修改 在@cnicutar的评论之后,我以一种我认为更有意义的方式改写了下面的例子,希望以后对某人有用。我希望父母在监视其他事情的同时监视子进程,并在子进程失败/结束时对新exec进行新的fork调用。我想尝试使用unix信号来实现这个目标

#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    pid_t cpid;
    int status;
    cpid = fork();
    for (;;)
    {
        switch (cpid)
        {
        case -1 : //Fork failure
            exit(EXIT_FAILURE);
            break;

        case 0 : //Child Process
            exec(some function);
            return 0; //exit child process
            break;

        default : //Parent process
            if (waitpid(-1, &status, WNOHANG) != 1) cpid = fork(); //restart 
            //Do parent stuff here...
            break;
        }
    }
}

1 个答案:

答案 0 :(得分:2)

添加一个SIGCHLD处理程序不会给你带来太大的影响,因为你已经等了一段时间而且只是这样做 - 没有别的东西可以“打断”。

我建议的一个问题是,这个过程不会经常死亡/开始。

  

我的理解是我应该使用像SIGCHLD这样的东西   一直无法找到任何好的例子

您使用SIGCHLD知道何时等待。典型的SIGCHLD处理程序只在循环中执行waitpid,直到没有孩子离开。在您的情况下,您不需要,因为您的主代码是在waitpid停止的循环。


修改

您可以找到大量SIGCHLD处理的示例。一个这样的例子是How can I handle sigchld in C。在该代码中,在while之后,您可以fork

while((pid = waitpid(-1, &status, WNOHANG)) > 0)
        ;

pid = fork();
switch (pid)
...

重申一下,如果你这样做,每次孩子死亡时都会调用SIGCHLD,在你正确等待它之后,你可以fork另一个孩子。只有父母在此期间有更好的事情要做而不是仅阻止waitpid,这才有意义。


向智者说话。某些函数不能从信号处理程序中调用,以免您向程序中添加困难的错误。查找“异步信号安全”功能:这些只能从信号处理程序中调用。一些最常见的函数(如printfmalloc)无法从信号处理程序中调用。