如何从C ++中长时间运行的子进程获取输出

问题描述

从C ++程序中,我想要:

  • 启动子进程。
  • 等待直到发出一行输出
  • 捕获该行输出,并允许子进程继续运行。

这似乎应该是微不足道的,但是我现在已经尝试了两种方法,并且每次都遇到了类似的障碍。首先,我像这样使用boost::process

auto exe = boost::process::search_path("other_executable");
boost::process::ipstream output;
master_process_ = boost::process::child(exe,boost::process::std_out > output);
std::string important_line;
std::getline(output,important_line);

第二种方法是只使用popen

FILE* master_process_ = popen("other_executable","r");
char stdout_buffer[128];
while (fgets(stdout_buffer,sizeof(stdout_buffer),master_process_)) {
   // log print here
}

在这两种情况下,当程序尝试从管道中读取时(分别在getlinefgets中,程序都会阻塞,并且gdb显示它停留在低级读取功能中:

#0  0x00007ffff7dcc332 in __libc_read (fd=3,buf=0x555555581d40,nbytes=895) at ../sysdeps/unix/sysv/linux/read.c:26
#1  0x00007ffff794052c in read (__nbytes=<optimized out>,__buf=<optimized out>,__fd=<optimized out>) at /usr/include/x86_64-linux-gnu/bits/unistd.h:44
#2  boost::process::detail::posix::basic_pipe<char,std::char_traits<char> >::read (count=<optimized out>,data=<optimized out>,this=0x7fffffffcbd0)
    at /usr/include/boost/process/detail/posix/basic_pipe.hpp:93
#3  boost::process::basic_pipebuf<char,std::char_traits<char> >::underflow (this=0x7fffffffcb90) at /usr/include/boost/process/pipe.hpp:202
#4  0x00007ffff7c2351a in std::basic_istream<char,std::char_traits<char> >& std::getline<char,std::char_traits<char>,std::allocator<char> >(std::basic_istream<char,std::char_traits<char> >&,std::__cxx11::basic_string<char,std::allocator<char> >&,char) () from /lib/x86_64-linux-gnu/libstdc++.so.6

对于进一步的上下文,other_executable一个小型Python程序,当它自己运行时会发挥预期的作用(发出输出,一直存在)。它还打开了一个服务器,在这两种情况下我都可以正常通信,因此它肯定正在运行(GDB的分离消息进一步证实了这一点,ps也是如此)。

我在做什么错了?

解决方法

事实证明,这两种实现都可以正常工作-问题在于Python脚本没有刷新标准输出。我以为我很清楚,因为我正在发出Error: Problem with `mutate()` input `Proportion`. x could not find function "DHB" i Input `Proportion` is `Immunised/DHB(vacc)`. ,并且从终端调用时似乎很好,但是显然不是。

感谢@ paul-sanders这个指针。