【问题标题】:Enforce maximum size for boost ASIO queue强制提升 ASIO 队列的最大大小
【发布时间】:2017-02-25 21:17:51
【问题描述】:

我在网上找到的许多示例都建议使用队列来管理 async_write 使用的消息,而后者又使用完成处理程序,即 lambda,一旦 async_write 完成就会丢弃数据。例如,来自 boost 示例的聊天服务器:http://www.boost.org/doc/libs/1_62_0/doc/html/boost_asio/example/cpp11/chat/chat_server.cpp。适用代码如下:

  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 完成的速度快,因此队列在内存中任意增长,直到应用程序崩溃。

我尝试使用线程安全队列,如果队列达到一定大小,该队列会从前面弹出消息。问题是完成处理程序是唯一决定何时使用完数据的处理程序,因此我的方法失败了,因为它会在消息使用完毕之前弹出消息。

任何人都可以推动正确的方向吗?我可以使用两个队列来解决这个问题吗?

【问题讨论】:

    标签: c++ queue boost-asio


    【解决方案1】:

    您需要一个有界队列,并且您需要以某种方式处理队列已满的情况。

    如果您不需要线程安全(即如果您使用链),您可以考虑boost::circular_buffer

    否则Boost.Thread中有boost::sync_bounded_queue

    【讨论】:

    • 我觉得我使用的数据结构不是主要问题。这是与丢弃数据相关的算法。 async_write "write_msgs_.front().data()" 使用的数据需要存在于其他地方。它只需要在调用完成处理程序之前保持在范围内:“尽管可以根据需要复制缓冲区对象,但调用者保留底层内存块的所有权,它必须保证它们在调用处理程序之前保持有效。 "
    • @BrockHargreaves needs to live somewhere else. 这可以是另一个队列(没有帮助),也可以是对async_write 进行排队的函数堆栈。在第二种情况下,您需要阻止(例如使用未来)。换个角度想:如果生产者比消费者快(async_write),那么没有可能的解决方案,所以要么丢掉一些数据,要么让生产者等待消费者。
    猜你喜欢
    • 2019-10-14
    • 2010-11-24
    • 2018-06-24
    • 1970-01-01
    • 2012-07-25
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    相关资源
    最近更新 更多