问题
The following program:
#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;
}
outputs 383
. I would expect it to output 0
.
This is very nearly a copy-and-paste of the example from:
https://www.boost.org/doc/libs/1_71_0/doc/html/boost_process/tutorial.html#boost_process.tutorial.async_io
回答1:
There may be a few issues here. Firstly, I think the comment in the documentation...
Passing an instance of boost::asio::io_service to the launching function automatically cause it to wait asynchronously for the exit, so no call of wait is needed
...refers to the example after the code you've shown. Specifically...
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();
Where the io_service
is passed by reference to the child
ctor.
The comment is also slightly misleading. While it's true that the subsequent call to ios.run()
does wait asynchronously for the exit it also appears (boost 1.71.0) that the exit code is not fixed up as one might hope. The exit code is stored within the child
class as...
std::shared_ptr<std::atomic<int>> _exit_status;
From a quick scan of the source code it seems _exit_status->store(...)
is only invoked from the following members...
boost::process::child::running
boost::process::child::wait
boost::process::child::wait_until
So, even though the process has exited (assuming all went well) when ios.run()
returns one or more of running
, wait
or wait_until
must be called to make the exit code available.
As commented elsewhere by @sehe this looks like it's possibly a regression. If I can find a bug report I'll update this. In the meantime the workaround is to simply call c.wait()
before c.exit_code()
.
来源:https://stackoverflow.com/questions/59157240/boostprocess-async-io-example-doesnt-work