在 boost 进程异步子进程中 run() 之后是不是需要 wait()?

Posted

技术标签:

【中文标题】在 boost 进程异步子进程中 run() 之后是不是需要 wait()?【英文标题】:Is wait() needed after run() in boost process async child process?在 boost 进程异步子进程中 run() 之后是否需要 wait()? 【发布时间】:2018-10-01 10:18:07 【问题描述】:

我在异步模式下使用Boost Process 来获取stdoutstderr 并返回shell 命令的代码。在下面的代码sn-p中,是否需要调用c.wait()?根据Boost Process 1.68 documentation 不需要,因为根据boost process 1.65.1 的that 需要。

std::string command = "ls";
boost::asio::io_service ios;
std::future<std::string> dataOut;
std::future<std::string> dataErr;
bp::child c(command, bp::std_in.close(), bp::std_out > dataOut, bp::std_err > dataErr, ios);
ios.run();
c.wait();
stdOut = dataOut.get();
stdErr = dataErr.get();
returnStatus = c.exit_code();

现在,我正在使用Boost 1.68,当我删除对c.wait() 的调用时,我得到127returnStatus,而不是预期的0,当我添加c.wait() 时得到的称呼。调用c.wait() 有什么不同?

【问题讨论】:

关于wait() 不必要的注释似乎与类文档冲突。 boost.org/doc/libs/1_68_0/doc/html/boost/process/… 我认为文档需要更多工作。 @RichardHodges,ios.run() 不等待进程退出吗?如果是,那么为什么需要 c.wait()? 您会认为内部waitpid() 已被调用(甚至可能在第二个服务线程上),但我没有花时间查看源代码来检查。为什么不写一点 MCVE 来证明文档是错误的并将其作为一个 bug 提出来呢? 【参考方案1】:

是的,run() 通常会等待异步操作完成。

但是,您可以使用 run() 的替代终止符

当异常来自处理程序时 当另一个线程调用stop() 当异步信号改变程序流程时

在这种情况下,建议您仍然使用wait(),以免出现僵尸。除此之外,on_exit() handler 是更灵活的方法,因为它允许您在同一个io_context/io_service 实例上多路复用多个进程,并且仍然尽快响应子进程完成。

【讨论】:

我在 Centos7 机器上多次运行上述程序,无论是否调用 c.wait()。在每种情况下,像 'ls'、'pwd'、'uname' 这样的简单命令在没有 c.wait() 调用的情况下其 c.exit_code() 值为 127,而在使用 c.wait() 时它变为 0称呼。因此,通常 run() 似乎不会等待同步操作完成。

以上是关于在 boost 进程异步子进程中 run() 之后是不是需要 wait()?的主要内容,如果未能解决你的问题,请参考以下文章

Linux下异步回收子进程

使用带有超时的异步模式的boost进程运行进程

通过其子进程分析一个进程并在之后杀死该子进程

boost子进程怎么获取父进程的参数

百万年薪python之路 -- 并发编程之 多进程二

僵尸 孤儿 守护 进程的理解