使用单个io_context运行多个超时进程

问题描述 投票:0回答:1

我稍微更改了here找到的示例,以从在 main 中定义的单个 io_context 对象运行所有进程,并传递给每个任务,从不同的线程运行。

我期望所有任务都能成功完成,因为它们所花费的时间应该少于超时时间。但是,我的所有任务都超时了。知道为什么吗?

#include <boost/asio.hpp>
#include <boost/process.hpp>
#include <iostream>

using duration = std::chrono::system_clock::duration;
namespace asio = boost::asio;
using namespace std::chrono_literals;

std::string ExecuteProcess(boost::filesystem::path  exe,
                           std::vector<std::string> args, //
                           duration                 time, //
                           std::error_code&         ec, 
               asio::io_context&        ioc) {
    namespace bp = boost::process;
    std::future<std::string> data, err_output;

    bp::group g;
    bp::child child(exe, args, ioc, g, bp::error(ec),
                    bp::std_in.null(),  //
                    bp::std_out > data, //
                    bp::std_err > err_output);

    if (std::error_code ignore; child.running()) {
        g.terminate(ignore);
    }

    if (data.wait_for(time) == std::future_status::ready) {
        ec.clear();
        return data.get();
    }

    ec = make_error_code(asio::error::timed_out);
    return {};
}

int main() {
    constexpr duration timeout = 20ms;
    constexpr auto     script2  = "sleep 0.00005; echo -n 'Hello world'";
    constexpr auto     script1 = "/usr/bin/curl http://httpbin.org/ip -m 5";

    asio::io_context         ioc;
 
    boost::asio::detail::thread_group collect_threads;
    for (int i = 0 ; i < 20 ; i++) {
        collect_threads.create_thread([&]() {
            std::error_code ec_;
            auto s = ExecuteProcess("/bin/bash",    {"-c", script2}, timeout, ec_, ioc);
            std::cout << "got " << ec_.message() << ": " << s << std::endl;
        });
    }
    ioc.run();
}

附言: 对于超时实现,我也在考虑使用

result = waitpid(pid, &status, WNOHANG)
而不是
std::future
。 然而,当我完成等待并且进程标准输出似乎正确时,检查
child.exit_code()
返回383,这意味着该进程仍在运行 - 不知道为什么。

c++ boost process boost-asio
1个回答
0
投票

线程创建需要时间,您的

ioc.run()
在线程开始使用
io_context
之前执行,因此
run()
会立即返回。

这可能是您想要的:

boost::asio::io_context ctx;
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> workGuard(ctx.get_executor());

ctx.run();

如果您想要

workGuard.reset()
停止,请在其他线程上调用
io_context::run()

© www.soinside.com 2019 - 2024. All rights reserved.