2012-07-25 122 views
3

我正在使用boost :: asio。我寫了一個負責從套接字異步讀取的類。 在我的應用程序中,可以在一次應用程序運行期間多次停止和啓動io_service。 因此,當服務停止時,我不得不擔心內存泄漏。 我來到了兩種解決方案:C++異步調用最佳實踐

  1. 類要求的異步請求提供的功能與使用ASIO一個緩衝區中讀取,並負責其釋放。這是一個明顯的解決方案,但我不喜歡它。傳遞一個你不需要的函數看起來很奇怪。

  2. 智能指針綁定到回調。例如這裏: http://pastebin.com/p8nQ5NFi

現在我使用的是第二個解決方案,但是但是我感覺,我發明了車輪。異步調用中緩衝區清理的常見做法是什麼?我的問題中有沒有隱藏的問題?

回答

4

shared_ptr方法相當普遍。但是,不要將shared_ptr作爲bind的附加參數傳遞,而是可以將shared_ptr作爲實例對象來代替this

boost::shared_ptr<my_class> ptr(this); 

boost::asio::async_read(stream, buffer, 
    boost::bind(&my_class::read_handler, ptr, 
    boost::asio::placeholders::error 
    boost::asio::placeholders::bytes_transferred)); 

通常情況下,由於該實例會通過shared_ptr,這可能會或可能不會在this的背景下進行管理,它是使用Boost.SmartPointer的enable_shared_from_this一個好主意。當一個類繼承自boost::enable_shared_from_this時,它提供了一個shared_from_this()成員函數,該函數返回一個有效的shared_ptr實例到this

class my_class: public boost::enable_shared_from_this<my_class> 
{ 
    void read() 
    { 
    boost::asio::async_read(stream, buffer, 
     boost::bind(&my_class::read_handler, shared_from_this(), 
      boost::asio::placeholders::error 
      boost::asio::placeholders::bytes_transferred)); 
    } 
}; 

boost::shared_ptr<my_class> foo(new my_class()); 
foo->read(); 

在這個片段中,foo.get()foo->shared_from_this()都指向同一個實例。這有助於防止難以找到內存泄漏。例如,在原始示例代碼中,如果在嘗試調用AsyncReadMessageAsyncReadHandler的複製構造函數拋出,則Protocol::AsyncReadMessage中發生內存泄漏。 Boost.Asio的asynchronous TCP daytime server和許多examples顯示enable_shared_from_this正在使用Boost.Asio內。爲了更深入的瞭解,this問題明確涵蓋了異步Boost.Asio函數和shared_ptr


另外,在原來的代碼,它可以更容易地使Protocol::AsyncHelper模板類代替具有它是一個非模板類與模板構件的功能。這將允許AsyncHelper接受協議,流和處理程序作爲構造函數參數,將它們存儲爲成員變量。另外,它使得bind調用稍微容易閱讀,因爲它減少了需要傳遞的參數數量,並且由於成員函數不再是模板,所以不需要指定它們的完整類型。 Here是一個例子的快速傳遞。