我正在使用boost::asio编写服务器。我有多个线程,每个线程拥有它自己的io_service
对象。当没有要执行的完成处理程序时,我使用io_service::work
对象来保持io_service
运行。在某些时刻,我调用stop
个io_service
对象的方法来完成调用io_serice::run
的线程。但在某些情况下,当我调用stop
时,我已在io_service
对象竞争处理程序中发布了未完成的操作。调用stop
会阻止发布的竞争处理程序执行,但这对我来说是不可接受的,因为我需要在停止线程之前完成所有待处理的工作。如何在调用stop
的{{1}}方法之前先等待所有挂起的完成处理程序执行?
答案 0 :(得分:2)
只需重置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秒后完成后台线程。