повысить безопасность выполнения процессов () и exit_code ()

я использую boost::process::child а также boost::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();
}

1

Решение

Поскольку вы запускаете только io_service::run() в главном потоке все обработчики завершения также работают там. Там нет потоков.

Не забудьте передать io_service ребенку и использовать on_exit обработчик:

Жить на Колиру

#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

Другие решения

Единственное решение, которое сработало для меня, заключается в следующем

  1. график завершения чтения
  2. всегда проверяйте звонки child::running()
  3. при наборе кода ошибки не перепланировать

Когда канал прерывается (из-за сбоя), обработчик завершения чтения получает для аргумента boost :: error_code значение true. Несмотря на это, я видел случаи, когда child :: running () также имеет значение false, когда boost :: error_code НЕ установлен.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector