增强:异步地等待将来完成

时间:2019-02-13 16:47:19

标签: c++ boost promise future asio

这是我的问题,可以说我有一大堆需要同步执行的同步代码,而我有一个线程池。我可以为此“任务”提供标注,该标注可以为Boost Promise设置值。

现在我等待一个调度程序线程以io_service的身份运行,该服务将通过io.post获得“请求”,从池中选择一个工作线程,将作业提交给它,然后传递“标注”(在工作线程上运行并“执行” promise.set_value”。 我想发生的是某种将在“ io_service”上执行的“继续”。 我可以做到的一种方法是,“标注”将在io_service上提交“新作业”,该作业可以是从“请求启动器”传递的lambda,因此不使用“承诺”和“未来”。 问题是我可以以某种方式使用“未来”吗?以某种方式使“ promise.set_value”提交此“延续”。

我尝试了以下代码,如下所示:

 void worker(promise<int>& p) {
  sleep(10);
  p.set_value(10);
}


int main(int argc, char **argv) {
    io_service io;
    io_service::work work(io);
    promise<int> p;
    io.post([&] {
        std::cout << "submission id:" << boost::this_thread::get_id() << std::endl;
        boost::thread my_thread(&worker, boost::ref(p));
        p.get_future().then(launch::async, [](future<int> p){
            std::cout << "completion thread id:" << boost::this_thread::get_id() << std::endl;
        });
    });
    io.run();
}

这是输出: 职位编号:7f0c7b825b80 工作完成编号:7f0c798be700

似乎它正在不同的线程上运行完成,并且我需要在“ io_service”上调用它..我应该从侧线程“发布”新的“ JOB”吗?

我使用的是1.65助推器。

2 个答案:

答案 0 :(得分:0)

您可能想看看boost.future:

https://www.boost.org/doc/libs/1_69_0/doc/html/thread/synchronization.html#thread.synchronization.futures.then

boost::future优于std::future,因为您可以使用.then([executor], continuation_function)将延续延续到未来。

在最新版本的asio中,io_context::executor_type(来自.get_executor())和io_context::strand为执行者建模。

答案 1 :(得分:0)

基本上,当一个函数提供结果时,您想同步post附加代码。使用promise进行同步通信是多余的(请记住promise使用同步对象)。

绕过post,您最初的想法是io_service延续到promise,是一个更好的主意:

int worker() {
    this_thread::sleep_for(2s);
    return 10;
}

int main(int argc, char **argv) {
    io_service io;
    io_service::work work(io);
    thread my_thread; // assuming this represents the thread pool
    io.post([&] {
        std::cout << "submission id:" << this_thread::get_id() << std::endl;
        my_thread = thread([&io] { // assuming this represents posting a task to the pool
            auto result = worker();
            io.post([&io, result] {
                std::cout << "completion thread id:" << this_thread::get_id()
                          << ", result:" << result << std::endl;
            });
        });
    });
    io.run();
}

注意。另一个答案的想法是这样的:

    p.get_future().then(io.get_executor(), [](future<int> p) {
        std::cout << "completion thread id:" << boost::this_thread::get_id() << std::endl;
    });

它对您不起作用,因为io_context::executor_typefuture.then([Executor&],...)在Boost 1.66中可用(由于ASIO执行程序中缺少try_executing_one(),它仍然可能不起作用)。 / p>