在linux中创建子进程并处理可能失败的最佳方法

时间:2016-05-23 15:07:37

标签: c++ linux fork exec

我有父进程,必须创建几个子进程。我发现的最佳方式是使用fork + execl。但是父母的过程需要知道具体孩子的execl是否失败,而且我不知道如何实现它。

        int pid = fork();
        if (pid < 0) {
           std::cout << "ERROR on fork." << std::endl;
        } if (pid == 0) {
           execl("/my/program/full/path", (char *)NULL);
           exit(1);
        }
        else {
            if (/*child's process execl fails*/) {
                std::cout << "it failed" << std::endl
            } else {
                std::cout << "child born" << std::endl
            }
        }

我认为这个想法并不好:

int status(0);
sleep(100);
int res = waitpid(pid, &status, WNOHANG);
if (res < 0 && errno == 10) {
    std::cout << "it failed" << std::endl
} else {
    std::cout << "child born" << std::endl
}

因为希望子进程在100毫秒后死亡并不好,我想知道这一点肯定会发生。

我还认为为此类检查创建shared_memory或特殊管道连接是针对Bees的Cannon。

必须有一个简单的解决方案,我还没有找到。

实现这一目标的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

作为一般解决方案,您可以使用sigaction()在父级中注册信号处理程序(SIGUSR1)。

在子项中:取消注册信号处理程序,如果execl()调用失败,则需要将SIGUSR1发送给父项。

在父级中:每个子级pid我们将存储在std :: set中。创建所有子项后,您只需创建一个单独的线程来跟踪子项。在线程函数中,只需调用wait()并从集合中删除pid。另一种监听SIGCHLD信号的方法(但它会导致更复杂的解决方案,所以如果生成另一个线程是一个选项,我会使用线程)。

当集合为空时,我们已经完成了。