当子进程退出时通知父进程

3

假设我有一个父进程,它会派生几个工作进程(子进程)。 我想在其中一个子进程崩溃(被杀死)时得到通知。

最佳方法是什么呢? 我使用 C 或 C++ 进行编程。 我在 UNIX 上。并且使用 fork_and_exec 派生了子进程。

1个回答

3
如果你只想在子进程退出时(正常或异常退出)获得通知,可以在父进程中编写一个处理器来处理SIGCHLD信号。每当由该进程生成的进程终止时,此处理程序将被执行。
但是,在此处理程序内部可以进行的操作非常有限。如果接收到其他信号,则立即中断该处理程序。甚至变量赋值也不是信号处理程序内部的安全操作-赋值可能需要两个或多个机器指令,并且可能会被新信号中断,因而导致该值未定义。只有那些类型为sig_atomic_t的变量可以在信号处理程序内部安全地赋值(对该类型变量的赋值保证在一条指令中完成)。
父进程还必须使用wait函数“等待”子进程-否则,在终止后,子进程将变成僵尸进程。
在我的情况下,这种解决方案已经足够了,因为我只需要减少类型为sig_atomic_t的计数器变量。如果需要在子进程终止时执行一些“严重”的处理,则需要另一种解决方案。其思路如下:
1. 在主进程内部,有一个专用线程,它将等待子进程的死亡(包括成功从主要进程返回、被SIGTERM和SIGKILL信号杀死以及任何其他异常终止)。
2. 为此,我们可以使用UNIX的waitid()方法,它允许我们指定我们正在等待的子进程、我们正在等待的事件类型(EXITED、STOPPED或CONTINUED),并在成功时提供关于终止进程的有用信息(例如子PID)。
3. 因此,在这个线程内部,我们使用waitid()来等待子进程,每当一个子进程死亡时,该函数都会终止并给我们提供有用的信息。
4. 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 使用率会非常高(我猜这是一种忙等待的形式)。因此,我们必须时不时地调用 sleep,给 CPU 一个休息的机会。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接