2

以下程序:

#include <boost/asio.hpp>
#include <boost/process.hpp>
#include <iostream>

namespace bp = boost::process;

int main() {
    boost::asio::io_service ios;
    std::vector<char> buf(4096);

    bp::async_pipe ap(ios);

    bp::child c("/bin/ls", bp::std_out > ap);

    boost::asio::async_read(ap, boost::asio::buffer(buf),
            [](const boost::system::error_code &ec, std::size_t size){});

    ios.run();
    int result = c.exit_code();
    std::cout << result << std::endl;
}

输出383。我希望它能够输出0

这几乎是来自以下示例的复制和粘贴:

https://www.boost.org/doc/libs/1_71_0/doc/html/boost_process/tutorial.html#boost_process.tutorial.async_io

4

1 回答 1

3

这里可能存在一些问题。首先,我认为文档中的评论......

将 boost::asio::io_service 的实例传递给启动函数会自动导致它异步等待退出,因此不需要调用 wait

...指的是您显示的代码之后的示例。具体来说...

boost::asio::io_service ios;
std::vector<char> buf(4096);

bp::child c(bp::search_path("g++"), "main.cpp", bp::std_out > boost::asio::buffer(buf), ios);

ios.run();
int result = c.exit_code();

io_service通过引用传递给childctor的地方。

该评论也有点误导。虽然随后的调用ios.run() 确实异步等待退出,但它也出现(提升 1.71.0)退出代码没有像人们希望的那样修复。退出代码存储在child类中...

std::shared_ptr<std::atomic<int>> _exit_status;

从源代码的快速扫描看来,它似乎_exit_status->store(...)只从以下成员调用...

boost::process::child::running
boost::process::child::wait
boost::process::child::wait_until

因此,即使进程已经退出(假设一切顺利),当ios.run()返回一个或多个running, waitor时wait_until必须调用以使退出代码可用。

正如@sehe 在其他地方评论的那样,这看起来可能是一种回归。如果我能找到错误报告,我会更新它。同时,解决方法是简单地调用c.wait()before c.exit_code()

于 2019-12-03T18:26:20.710 回答