0

我正在尝试编写一个程序来检查退出的子进程并在它们退出时重新启动它们。它需要在进程退出时重新启动它们,而无需等待任何其他进程退出。我有点失落。这是我到目前为止所做的代码。它没有完成或正确,真的。但也许有人可以指出我正确的方向?

for(int ifile = 1; ifile < 4; ifile++){

    child_pid[ifile - 1] = vfork();

    if(child_pid[ifile - 1] == -1){
        cerr << "fork error on " << argv[ifile] << endl;
    }
    else if(child_pid[ifile - 1] == 0){
        execl(argv[ifile], argv[ifile], NULL);
    }
}

for(int index = 0; index < 3; index++){
    do{
        wait_pid = waitpid(child_pid[index], &status, WUNTRACED);
        if(WIFEXITED(status)){
            count++;
            child_pid[index] = vfork();
            if(child_pid[index] == -1){
                cerr << "rescheduled process error" << endl;
                return -1;
            }
            else if(child_pid[index] == 0){
                cout << "Rescheduling " << argv[index + 1] << endl;
                execl(argv[index + 1], argv[index + 1], NULL);
            }
        }
    }while(count != 4);
}
4

2 回答 2

3

您的方法的问题是您将阻止 waitpid 直到第一个 [0th] 孩子死亡,而其他任何孩子都可能在此期间死亡。

你可以:

(1) 使用wait() 代替waitpid()。这将处理任何孩子,但它会阻止。

(2) 在循环时使用 waitpid() 和 WNOHANG 标志轮询死去的孩子。

(3) 设置信号处理程序并捕获 SIGCHILD 信号。将 waitpid/WNOHANG 循环放在您的处理程序中,但在它之外执行重新启动的工作。

EG 处理程序执行以下操作:

   while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) 
   {
        //set a flag or whatever; not wise to fork/exec in handler
   }
于 2011-05-08T02:28:45.073 回答
2

我不确定你为什么想要这个WUNTRACED选项。在它说“停止”的地方,我很确定它与暂停的含义相同,而不是退出。

两种可能的方法:

而不是循环,只需执行以下操作:

pid_t pid = wait();

它将阻塞直到进程完成。

或者,将第三个参数更改为waitpid()from WUNTRACEDto WNOHANG。这将让它测试每个进程而不会阻塞。在这种情况下,您可能希望在每次循环结束时添加一个小睡眠。

于 2011-05-08T02:23:52.610 回答