2017-02-25 107 views
1

我在網上找到的很多例子都建議使用隊列來管理async_write所使用的消息,該消息又使用完成處理程序i..e,lambda,一旦async_write被丟棄完成。例如,來自boost示例的聊天服務器:http://www.boost.org/doc/libs/1_62_0/doc/html/boost_asio/example/cpp11/chat/chat_server.cpp。適用的代碼如下:強制升級ASIO隊列的最大大小

void do_write() 
    { 
    auto self(shared_from_this()); 
    boost::asio::async_write(socket_, 
     boost::asio::buffer(write_msgs_.front().data(), 
      write_msgs_.front().length()), 
     [this, self](boost::system::error_code ec, std::size_t /*length*/) 
     { 
      if (!ec) 
      { 
      write_msgs_.pop_front(); 
      if (!write_msgs_.empty()) 
      { 
       do_write(); 
      } 
      } 
      else 
      { 
      room_.leave(shared_from_this()); 
      } 
     }); 
    } 

然而,在我使用它的應用程序,這是可能的郵件推入write_msgs_比ASYNC_WRITE快可以完成,因此隊列變得任意大的內存中,直到應用程序崩潰。

我嘗試使用線程安全隊列,如果隊列達到特定大小,則會從前端彈出消息。問題是完成處理程序是唯一一個可以決定何時完成數據使用的處理程序,因此我的方法失敗了,因爲它會在消息被使用之前彈出消息。

任何人都可以提供正確的方向?我可以使用兩個隊列來解決這個問題嗎?

回答

0

您需要一個有界的隊列,並且您需要以某種方式處理隊列已滿的情況。

如果您不需要線程安全性(即,如果您使用線束),則可以考慮boost::circular_buffer

否則,在Boost.Threadboost::sync_bounded_queue

+0

我覺得我使用的數據結構不是主要問題。這是與丟棄數據相關的算法。 async_write「write_msgs_.front()。data()」使用的數據需要在其他地方居住。它只需要保持在作用域中,直到調用完成處理程序爲止: 「雖然可以根據需要複製緩衝區對象,但調用者會保留底層內存塊的所有權,這必須保證它們保持有效,直到處理程序被稱爲「。 –

+0

@BrockHargreaves'需要住別的地方.'可以是另一個隊列(這沒有幫助),或者是對'async_write'進行排隊的函數堆棧。在第二種情況下,您需要阻止(例如使用未來)。 用另一種方式思考一下:如果生產者比消費者('async_write')更快,就沒有可能的解決方案,所以要麼丟掉一些數據,要麼讓生產者等待消費者。 – sbabbi