c++ - 在 async_write 挂起时写入 streambuf 是否安全?

标签 c++ c++11 boost-asio

考虑以下代码:

void TCP::sendMessage(const std::string& msg) {
  std::ostream os{&m_send_streambuf};
  os << msg;

  if (not m_pending_send) {
    doSend();
  }
}

void TCP::doSend() {
  m_pending_send = true;
  boost::asio::async_write( m_socket, m_send_streambuf
                          , [this](boost::system::error_code ec, std::size_t len)
                            {
                              if (ec) {
                                  throw std::runtime_error(ec.message());
                              }

                              m_send_streambuf.consume(len);

                              if (m_send_streambuf.size() >= 1) {
                                // There's still some data to send
                                doSend();
                              }
                              else {
                                m_pending_send = false;
                              }
                          });
}

m_send_streambuf 是一个 boost::asio::streambuf 并且 m_pending_send 指示异步写入是否正在等待。

我不确定像这样使用 streambuf 是否是个好主意,因为对 sendMessage 的调用将修改缓冲区,而异步写入可能正在运行.

那么,像这样使用streambuf 安全吗?或者我应该使用某种双缓冲?

最佳答案

The documentation of async_write关于 buffers 参数状态:

One or more buffers containing the data to be written. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.

因此您不应该对流缓冲区执行任何其他写操作,因为这可能会使传递给 async_write 的底层内存块无效。

您可以做的是简单地使用 stringstream 来缓冲传入的数据,一旦挂起的异步写入完成,将内容刷新到提升流缓冲区并分派(dispatch)新的异步写入。当然,您可以使用更复杂的机制,例如维护一个流缓冲区池以保留其状态信息(待定或可用),并在每次调用 sendMessage 时从池中获取一个新的流缓冲区并分派(dispatch)一个新的流缓冲区异步写入。这完全取决于您的要求 - 吞吐量和延迟或内存消耗。

关于c++ - 在 async_write 挂起时写入 streambuf 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33078400/

相关文章:

c++ - 模板参数数量错误

c++ - 复制 std::vector 但将 lambda 应用于每个元素

c++ - Boost::Asio 同步客户端超时

c++ - 检查两个数字是否互为排列?

c++ - 将元素添加到已排序的链表

c++ - 为什么 std::cbegin() 不在容器上调用 .cbegin() ?

c++ - 在模板类的模板成员函数中设置优先于构造函数

c++ - boost::asio QNX 链接器错误

c++ - 在 Visual C++ 中链接 libboost_system 时出错

python - 如何在 OpenCV 中计算焦距?