Я хочу, чтобы процесс ветвился, а затем сделать следующее в родительском:
Дождитесь его естественного завершения или истечения времени ожидания, установленного родительским объектом (что-то вроде waitforsingalobject в Windows), после чего я убью процесс с помощью kill (pid);
Получить код завершения дочернего процесса (при условии естественного завершения)
Мне нужно иметь доступ к std :: cout дочернего процесса от родителя.
Я попытался использовать waitpid (), однако, хотя это позволяет мне получить доступ к коду возврата, я не могу реализовать тайм-аут с помощью этой функции.
Я также посмотрел на следующее решение (https://www.linuxprogrammingblog.com/code-examples/signal-waiting-sigtimedwait), который позволяет мне реализовать тайм-аут, однако нет способа получить код возврата.
Я думаю, что мой вопрос сводится к тому, как правильно добиться этого в Linux?
Вы можете сделать № 1 и № 2 с sigtimedwait
функция и № 3 с pipe
:
#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.
Других решений пока нет …