Boost.Process v2: как асинхронно читать выходные данные, а также проверять завершениеC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Boost.Process v2: как асинхронно читать выходные данные, а также проверять завершение

Сообщение Anonymous »

Я создаю процесс и читаю его выходные данные с помощью сопрограмм Boost.Process v2 и C++ 20 следующим образом:

Код: Выделить всё

boost::asio::io_context gContext;
namespace bp = boost::process::v2;
struct Subprocess {
bp::process process;
std::string output;
};

// ...

auto pipe_stdout = std::make_unique(gContext);
auto pipe_stderr = std::make_unique(gContext);
auto subprocess = std::make_unique(Subprocess{
bp::process(gContext, "/bin/sh", { "-c", "my command" },
bp::process_stdio{ nullptr, *pipe_stdout, *pipe_stderr }),
std::string{} });
for (auto* pipe : { &pipe_stdout, &pipe_stderr }) {
boost::asio::co_spawn(
gContext,
[pipe = std::move(*pipe),
output = &subprocess->output]() -> boost::asio::awaitable {
while (true) {
std::array buf;
size_t len = co_await pipe->async_read_some(
boost::asio::buffer(buf), boost::asio::use_awaitable);
if (len == 0 && !pipe->is_open()) {
co_return;
}
output->append(buf.data(), len);
}
},
boost::asio::detached);
}
Я также настроил обработчик, который собирает информацию о процессе, если он завершился (

Код: Выделить всё

finished_
и Running_ имеют тип std::vector:

Код: Выделить всё

subprocess->process.async_wait(
[this, p = subprocess.get()](bp::error_code ec, int exit_code) {
assert(!ec);
auto it = std::ranges::find_if(
running_, [p](const auto& up) { return up.get() == p; });
finished_.emplace_back(std::move(*it));
running_.erase(it);
});
Затем у меня есть основной цикл, который проверяет, завершился ли процесс, и если да, то обрабатывает выходные данные:

Код: Выделить всё

while (true) {
while (!running_.empty() && finished_.empty()) {
gContext.run_one();
}
if (finished_.empty()) {
continue;
}
// process finished_.back(), get its output, etc.
finished_.pop_back();
}
Проблема, с которой я сейчас столкнулся, заключается в том, что иногда я не улавливаю весь вывод, кажется, что в буфере еще что-то осталось, и моя сопрограмма читает каналы еще не закончил. Как мне избежать этой гонки? Должен ли я каким-то образом прочитать вывод и дождаться выхода в той же сопрограмме?


Подробнее здесь: https://stackoverflow.com/questions/792 ... -terminati
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»