我想分叉一个进程,然后在父进程中执行以下操作:
等到它自然终止或父级设置的超时时间到期(比如windows中的waitforsingalobject),之后我将使用kill(pid)终止进程;
获取子进程的退出代码(假设它自然退出)
我需要从父进程访问子进程的std :: cout。
我尝试使用waitpid()但是这允许我访问返回代码,我无法使用此函数实现超时。
我还查看了以下解决方案(https://www.linuxprogrammingblog.com/code-examples/signal-waiting-sigtimedwait),它允许我实现超时,但似乎没有办法获得返回代码。
我geuss我的问题归结为,在Linux中实现这一点的正确方法是什么?
答案 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.