Linux中的分叉和等待(C ++)。

时间:2017-05-23 13:20:39

标签: c++ linux multithreading fork multiprocess

我想分叉一个进程,然后在父进程中执行以下操作:

  1. 等到它自然终止或父级设置的超时时间到期(比如windows中的waitforsingalobject),之后我将使用kill(pid)终止进程;

  2. 获取子进程的退出代码(假设它自然退出)

  3. 我需要从父进程访问子进程的std :: cout。

  4. 我尝试使用waitpid()但是这允许我访问返回代码,我无法使用此函数实现超时。

    我还查看了以下解决方案(https://www.linuxprogrammingblog.com/code-examples/signal-waiting-sigtimedwait),它允许我实现超时,但似乎没有办法获得返回代码。

    我geuss我的问题归结为,在Linux中实现这一点的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

您可以使用sigtimedwait功能执行#1和#2,使用pipe执行#3:

#include <unistd.h>
#include <signal.h>
#include <iostream>

int main() {
    // Block SIGCHLD, so that it only gets delivered while in sigtimedwait.
    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGCHLD);
    sigprocmask(SIG_BLOCK, &sigset, nullptr);

    // Make a pipe to communicate with the child process.
    int child_stdout[2];
    if(pipe(child_stdout))
        abort();

    std::cout.flush();
    std::cerr.flush();
    auto child_pid = fork();
    if(-1 == child_pid)
        abort();

    if(!child_pid) { // In the child process.
        dup2(child_stdout[1], STDOUT_FILENO); // Redirect stdout into the pipe.
        std::cout << "Hello from the child process.\n";
        std::cout.flush();
        sleep(3);
        _exit(3);
    }

    // In the parent process.
    dup2(child_stdout[0], STDIN_FILENO); // Redirect stdin to stdout of the child.
    std::string line;
    getline(std::cin, line);
    std::cout << "Child says: " << line << '\n';

    // Wait for the child to terminate or timeout.
    timespec timeout = {1, 0};
    siginfo_t info;
    auto signo = sigtimedwait(&sigset, &info, &timeout);
    if(-1 == signo) {
        if(EAGAIN == errno) { // Timed out.
            std::cout << "Killing child.\n";
            kill(child_pid, SIGTERM);
        }
        else
            abort();
    }
    else { // The child has terminated.
        std::cout << "Child process terminated with code " << info.si_status << ".\n";
    }
}

输出:

Child says: Hello from the child process.
Killing child.

如果sleep已被注释掉:

Child says: Hello from the child process.
Child process terminated with code 3.