子进程死亡时通知父进程

时间:2014-02-13 18:11:17

标签: unix process parent-child pid notify

假设我有一个父进程产生很少的工作者(子进程)。 我想在其中一个子进程崩溃(被杀)时得到通知。

获取此通知的最佳方式是什么? 我用c或c ++编程。 我在unix上。并使用fork_and_exec

生成了hte子进程

1 个答案:

答案 0 :(得分:3)

如果您只想在子进程退出(正常或异常)时收到通知,您可以在父进程中为 SIGCHLD 信号编写处理程序。只要此进程生成的进程消失,就会执行此处理程序。

但是,在此处理程序中可以执行的操作存在严重限制。如果收到其他信号,该处理程序将立即中断。即使变量赋值也不是信号处理程序内部的安全操作 - 赋值可以使用两个或更多机器指令,并且可以通过新信号中断,使值未定义。可以安全地在信号处理程序内部分配的唯一变量是 sig_atomic_t 类型的变量(保证在一条指令中完成对此类变量的赋值)。

家长还必须" 等待" (使用等待函数)用于子进程 - 否则,子进程将在终止后变为僵尸。

这个解决方案在我的情况下已经足够了,因为我只需要减少sig_atomic_t类型的计数器变量。如果你需要做一些"严肃的"当孩子死亡时处理,需要其他解决方案。这个想法可能如下:

  • 在主要流程中,有一个专门的线程,等待让孩子死亡(这包括成功从主要人员返回,被SIGTERM和SIGKILL信号杀死以及任何其他异常终止)。
  • 为此,我们可以使用UNIX waitid()方法,它允许我们指定我们正在等待的孩子,我们正在等待的事件类型(EXITED,STOPPED或CONTINUED)以及成功给出我们有关终止过程的有用信息(例如孩子的PID)。
  • 因此,在这个线程内部,我们使用 waitid()等待孩子,每次孩子死亡时,这个功能终止给我们提供有用的信息。
  • 在waitid()返回后,我们应该检查它的返回值和errno以查看是否一切正常。如果是的话,我们可以执行我们的清理程序(当孩子死亡时我们想要执行的代码块),然后我们继续监听更多的死亡(听起来很糟糕)。

C ++示例可以在下面找到 - 请注意我没有使用线程等待孩子,但是不应该修改示例以使用线程。

#include <iostream>
#include <sys/types.h>
#include <unistd.h>

int spawn(char* process_name, char** arguments){
    pid_t child_id = fork();

    if (child_id != 0)
        return child_id;
    else{
        execvp(process_name, arguments);
        fprintf(stderr, "An error occured while executing new process.\n");
        abort();
    }
}


int main(int argc, const char * argv[])
{
    char* arguments[] = {
        "/Path_to_Child_Exe/Child_Process",
        nullptr
    };

    int i=0;
    while (i++ < 10)
        spawn((char*) "/Path_to_Child_Exe/Child_Process", arguments);


    while (true){
        siginfo_t exit_info;
        int retVal = waitid(P_ALL, -1, &exit_info, WEXITED);

        if (retVal == -1 && errno == ECHILD){
            std::cout << "No more children.\n";
            break;
        }

        std::cout << "Child with PID " << exit_info.si_pid << " terminated.\n";

        sleep(1);
    }

    return 0;
}

同样重要的是要注意我们在while循环的每次迭代结束时调用sleep。在等待孩子的线程中也应该这样做。否则,如果我们在没有子进程的情况下不停顿地调用waitid()函数,CPU使用率将非常高(我猜是一种忙碌的等待形式)。因此,我们必须时不时地打电话给睡眠,让CPU有机会休息。