3

我创建了一个监视子进程并在它失败或退出时重新启动它的基本示例。这样做的首选/更强大的方法是什么?持续轮询状态变化是一种好习惯吗?我的理解是我应该使用类似的东西,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;
        }
    }
}
4

1 回答 1

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


给智者的话。有些函数不能从信号处理程序中调用,以免给程序添加困难的错误。查找“异步信号安全”函数:这些并且只有这些可以从信号处理程序中调用。一些最常见的函数(如printfand malloc)不能从信号处理程序中调用。

于 2014-03-05T00:33:04.457 回答