C++ boost process running()和exit_code()线程安全

C++ boost process running()和exit_code()线程安全,c++,pipe,ipc,boost-asio,boost-process,C++,Pipe,Ipc,Boost Asio,Boost Process,我正在使用boost::process::child和boost::process::async_pipe启动一个应用程序,并异步读取(通过boost::asio的方式)每当发生这种情况时应用程序在屏幕上输出的所有内容 我还想使用child::running()方法检查应用程序是否处于活动状态;如果没有运行,我想使用child::exit\u code读取退出代码 这是非常有用的尤其是,因为这是一种通知应用程序意外崩溃或退出的方法(我找不到更好的方法);当应用程序退出时,将使用boost::sy

我正在使用
boost::process::child
boost::process::async_pipe
启动一个应用程序,并异步读取(通过
boost::asio
的方式)每当发生这种情况时应用程序在屏幕上输出的所有内容

我还想使用
child::running()
方法检查应用程序是否处于活动状态;如果没有运行,我想使用
child::exit\u code
读取退出代码

这是非常有用的尤其是,因为这是一种通知应用程序意外崩溃或退出的方法(我找不到更好的方法);当应用程序退出时,将使用
boost::system::error\u code
set调用回调

您知道我是否可以在由
async\u pipe::async\u read\u some
调用的回调中使用这两个方法吗

一般来说,更简单的问题是
child::running()
child::exit_code()
是否是线程安全的(在Windows和Linux中)

namespace bp=boost::process;
char my_缓冲区[1024];
boost::asio::io_服务io;
bp::异步管道中的管道(io);
无效句柄\u管道\u读取(常量boost::系统::错误代码&ec,标准::大小\u t字节\u传输);
无效附表_read(){
in_pipe.async_读取一些(
boost::asio::buffer(my_buffer),
boost::绑定和处理\u管道\u读取,
boost::asio::占位符::错误,
boost::asio::占位符::字节(已传输);
}
无效句柄\u管道\u读取(
常量boost::系统::错误代码和ec,
std::大小\u t字节\u传输
)
{
//问:这个调用可能吗?“handle\u pipe\u read”可以在任何线程中运行
如果(c->running())

std::cout因为您只在主线程上运行
io_服务::run()
,所以所有的完成处理程序也在那里运行。没有线程

请记住将io_服务传递给子级,并使用退出时的
处理程序:

#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完成阅读
  • 始终检查调用
    child::running()
  • 出现错误时,请不要重新安排代码集

  • 当管道中断时(由于崩溃),读取的完成处理程序将boost::error_code参数设置为true当boost::error\u代码未设置时也为false。

    这是一个我不知道的可爱的函数。让我检查一下,我会回来找你。有一个问题想问你,以防万一:你知道boost::process::on\u出口在哪里执行吗?它是一个回调,可以在任何线程中执行,就像对所有boost::asio处理程序执行的那样?测试后,我可以n还可以看到,如果子应用程序崩溃,则不会调用此处理程序…因此,我仍然不确定收到崩溃通知的最佳方式是什么…可能还使用wait()如果应用程序未运行且未正确终止,则会引发异常。我在第一句中告诉过你:这是一个完成处理程序,在服务线程(运行
    io\u service::run()
    )上调用。如果有多个线程运行服务,则不知道是哪个线程(因此,使用钢绞线并将管道贴在靠近服务设施的地方)@Abruzzofortegentile我希望在_出口处调用
    
    
    #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)