BOOST PROCESS RUNTUN()和EXIT_CODE()线程安全



我正在使用 boost::process::childboost::process::async_pipe来启动应用程序并异步(通过boost::asio的均值),每当发生这种情况时,应用程序在屏幕上输出的所有内容。

我还想使用child::running()方法检查应用程序是否活着;如果不运行,我想使用child::exit_code读取出口代码。

这是非常有用的,尤其是,因为这是一种通知应用程序崩溃或出乎意料地退出的方式(我找不到更好的方法);当应用退出时,使用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();    
 }

由于您仅在主线程上运行io_service::run(),因此所有完成处理程序也在那里运行。没有线程。

记住将io_service传递给孩子,然后使用on_exit处理程序:

活在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. 安排完成阅读
  2. 始终检查致电child::running()
  3. 在error_code设置上不重新安排

当管道被损坏时(由于崩溃),读取的完成处理程序的boost :: error_code参数设置为true。尽管如此,我已经看到了Child :: runn()未设置boost :: error_code时也为false的情况。

最新更新