提升进程running()和exit_code()线程安全性 [英] boost process running() and exit_code() thread safety

查看:133
本文介绍了提升进程running()和exit_code()线程安全性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using boost::process::child and boost::process::async_pipe to start an application and read asynchronously (through the means of boost::asio) everything that app outputs on screen whenever this happens.

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

I want to check also if the application is alive by using child::running() method; if not running I'd like to read the exit code using child::exit_code.

这非常有用,特别是因为它是一种通知应用程序崩溃或意外退出的方法(我找不到更好的方法);当应用退出时,使用boost::system::error_code设置调用回调.

This is very useful ESPECIALLY as it is a way to be notified about an application crashing or exiting unexpectedly (I could not find a better way); when the app exits the callback is called with boost::system::error_code set.

您知道我是否可以在async_pipe::async_read_some调用的回调中使用这两种方法?

Do you know if I can use these two methods inside the callback called by async_pipe::async_read_some ?

通常,更简单的问题是child::running()child::exit_code()是否是线程安全的(在Windows和Linux中).

In general the much more simple question would be if child::running() and child::exit_code() are thread safe (in both Windows and 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(),因此所有完成处理程序也将在此处运行.没有线程.

Since you only run the io_service::run() on the main thread, all completion handlers also run there. There's no threading.

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

Remember to pass the io_service to the child, and use the on_exit handler:

在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)

这篇关于提升进程running()和exit_code()线程安全性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆