2013-03-04 44 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