我正在使用boost::process::child
和boost::process::async_pipe
来启动应用程序并异步读取(通过boost::asio
)应用程序在屏幕上输出的所有内容。
我想使用child::running()
方法检查应用程序是否处于活动状态;如果没有投放,我想使用child::exit_code
阅读退出代码。
这是非常有用的 ESPECIALLY ,因为它是一种通知应用程序崩溃或意外退出的方式(我找不到更好的方法);当应用程序退出回调时,会调用boost::system::error_code
设置。
您知道我是否可以在async_pipe::async_read_some
调用的回调中使用这两种方法?
一般来说,更简单的问题是child::running()
和child::exit_code()
是否是线程安全的(在Windows和Linux中)。
namespace bp = boost::process;
char my_buffer[1024];
boost::asio::io_service io;
bp::async_pipe in_pipe(io);
void handle_pipe_read(const boost::system::error_code &ec, std::size_t bytes_transferred);
void schedule_read() {
in_pipe.async_read_some(
boost::asio::buffer(my_buffer),
boost::bind(&handle_pipe_read,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_pipe_read(
const boost::system::error_code &ec,
std::size_t bytes_transferred
)
{
// Q: Is this call possible? 'handle_pipe_read' can run in any thread
if(c->running())
std::cout << "I am alive" << std::endl;
else
std::cout << "EXIT CODE:" << c->exit_code() << std::endl;
if(ec) return; //app probably exit
// Do something with buffer and re-schedule
schedule_read();
}
int main() {
bp::child c("my_program_url", bp::std_out > in_pipe);
any_c = &c;
schedule_read();
io.run();
}
答案 0 :(得分:1)
由于您只在主线程上运行io_service::run()
,因此所有完成处理程序也在那里运行。没有线程。
请记住将io_service传递给子节点,并使用on_exit
处理程序:
<强> Live On Coliru 强>
#include <boost/process.hpp>
//#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <system_error>
#include <utility>
#include <iostream>
namespace bp = boost::process;
char my_buffer[1024];
boost::asio::io_service io;
bp::async_pipe in_pipe(io);
void handle_pipe_read(const boost::system::error_code &ec, std::size_t bytes_transferred);
void schedule_read() {
in_pipe.async_read_some(
boost::asio::buffer(my_buffer),
boost::bind(&handle_pipe_read, _1, _2));
}
void handle_pipe_read(const boost::system::error_code &ec, std::size_t bytes_transferred) {
if (ec)
return; // app probably exit
// Do something with buffer and re-schedule
std::cout.write(my_buffer, bytes_transferred);
if (in_pipe.is_open())
schedule_read();
}
int main() {
bp::child c("/bin/ls", bp::std_out > in_pipe,
bp::on_exit([](int code, std::error_code ec) {
std::cout << "Child exited (" << code << "): " << ec.message() << std::endl;
in_pipe.close();
}), io);
schedule_read();
io.run();
std::cout << "Service done (" << c.exit_code() << ")" << std::endl;
}
打印:
a.out
main.cpp
Child exited (0): Success
Service done (0)
答案 1 :(得分:0)
对我有用的唯一解决方案是以下
child::running()
当管道损坏(由于崩溃)时,读取的完成处理程序将boost :: error_code参数设置为true。尽管如此,我还是看到了当:: not_proke_code未设置时,child :: running()的情况也是假的。