如何清除已在io_service::strand
排队的所有已发布任务?我没有看到来自boost文档的类似方法。
答案 0 :(得分:7)
我还没有找到它的需要,因为通过正确设计异步调用链可以正确解决它。通常,Boost.Asio API经过精心设计,可以防止复杂的应用程序在异步流程中变得复杂。
如果您已经检查了调用链,并且绝对肯定重新设计它们的努力比引入清除链的复杂性带来更大的当前和未来风险,那么有一种方法可以实现它。但是,它确实有一个主要的副作用,即删除strand
及其关联的io_service
中的所有未被发送的处理程序。
当strand
被销毁时,它的destructor会调度未调用的处理程序,以便在io_service
上进行延迟调用,从而保证非并发性。 {@ 1}} destructor表示已销毁已调度为延迟调用的未处理的处理程序对象。因此,通过控制io_service
和strand
的生命周期,可以清除链中的处理程序。
这是一个包含辅助类io_service
的过于简化的示例。
clearable_strand
为了最大限度地减少效果以便仅销毁#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/optional.hpp>
#include <boost/utility/in_place_factory.hpp>
class clearable_strand
{
public:
clearable_strand(boost::asio::io_service& main_io_service)
: main_io_service_(main_io_service)
{
clear();
}
public:
template <typename Handler>
void post(const Handler& handler)
{
// Post handler into the local strand.
local_strand_->post(handler);
// Local service now has work, so post its run handler to the
// main service.
main_io_service_.post(boost::bind(
&boost::asio::io_service::run_one, boost::ref(local_io_service_)));
}
void clear()
{
// Destroy previous (if any).
local_strand_ = boost::none;
local_io_service_ = boost::none;
// Reconstruct.
local_io_service_ = boost::in_place();
local_strand_ = boost::in_place(boost::ref(local_io_service_.get()));
}
private:
boost::asio::io_service& main_io_service_;
boost::optional<boost::asio::io_service> local_io_service_;
boost::optional<boost::asio::strand> local_strand_;
};
个处理程序,该类使用内部strand
而不是将io_service
附加到主strand
。当工作发布到io_service
时,处理程序会发布到主strand
,它将以菊花链形式连接并为本地io_service
提供服务。
及其用法:
io_service
运行该程序将输出void print(unsigned int x)
{
std::cout << x << std::endl;
}
int main()
{
boost::asio::io_service io_service;
io_service.post(boost::bind(&print, 1));
clearable_strand strand(io_service);
strand.post(boost::bind(&print, 2));
strand.post(boost::bind(&print, 3));
strand.clear(); // Handler 2 and 3 deleted.
strand.post(boost::bind(&print, 4));
io_service.run();
}
和1
。我想强调的是,这是一个过于简化的示例,并且以非复杂的方式提供线程安全性以匹配4
的线程安全性可能是一个挑战。
答案 1 :(得分:2)
这是不可能的,您需要根据您的目标重新设计您的设计。如果您希望某些高优先级处理程序在较低优先级的处理程序之前运行,则可以使用prioritized handler example。