2013-03-04 41 views

回答

7

我还没有找到它的需要,因为它可以通过正确设计异步调用链来正确解决。一般而言,Boost.Asio API的设计经过精心设计,可防止复杂应用程序在异步流程中变得复杂。

如果您已经检查了呼叫链,并且绝对肯定重新设计它们的努力比引入清理链的复杂性更具当前和未来风险,那么有一种方法可以实现它。但是,它的主要副作用是删除strand及其关联的io_service内的所有非引用处理程序。

当销售strand时,其destructor调度未调用的处理程序以在io_service上延期调用,以保证非并发性。 io_servicedestructor指出被调度为延期调用的未被调用的处理程序对象被销毁。因此,通过控制strandio_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(); 
} 

运行程序将输出14。我想强调一下,这是一个过于简单的例子,并且以非复杂的方式提供线程安全以匹配boost::asio::strand可能是一个挑战。

+0

谢谢你的解决方案。 – 2013-03-06 15:58:29

2

这是不可能的,你需要根据你的目标重新设计你的设计。如果您希望某些高优先级处理程序在低优先级处理程序之前运行,则可以使用prioritized handler example

+0

您的优先级处理程序示例非常有趣,它可以对我未来的项目非常有用。我会为此加书签。谢谢。 – 2013-03-06 15:57:21