如何在停止io_service之前等待所有挂起的完成处理程序被执行

How to wait for all pending completion handlers to be executed before stopping io_service?

本文关键字:挂起 处理 执行 程序 等待 io service      更新时间:2023-10-16

我正在使用boost::asio编写服务器。我有多个线程,每个线程都拥有自己的io_service对象。我使用io_service::work对象保持io_service运行时,没有完成处理程序执行。在某些时刻,我调用io_service对象的stop方法来完成调用io_serice::run的线程。但在某些情况下,当我调用stop时,我已经在io_service中发布了未完成的对象竞争处理程序。调用stop会阻止发布的竞争处理程序执行,但这对我来说是不可接受的,因为我需要在停止线程之前完成所有悬而未决的工作。如何在调用io_servicestop方法之前等待所有挂起的完成处理程序首先被执行?

重置work

当所有挂起的工作完成后,任何io_service::run()都将返回。

常见的模式是使用optional<work>,这样您就可以清除它。如果它是一个频繁的事情,您可以通过将它包装在一个支持raii的类中来减少一些心理开销:

Live On Coliru

#include <boost/asio.hpp>
#include <boost/optional.hpp>
struct work {
    using io_service = boost::asio::io_service;
    work(io_service& svc) : _work(io_service::work(svc)) 
    { }
    void release() {
        _work.reset();
    }
    void enlist(io_service& svc) {
        _work.emplace(io_service::work(svc));
    }
  private:
    boost::optional<io_service::work> _work;
};
#include <thread>
#include <iostream>
using namespace std::chrono_literals;
int main() {
    boost::asio::io_service svc;
    work lock(svc);
    std::thread background([&] { svc.run(); });
    std::this_thread::sleep_for(1s);
    std::cout << "releasing work";
    lock.release();
    background.join();
}

1秒后结束后台线程