考虑以下代码:

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 关于 缓冲区 参数状态:

因此,您不应对流缓冲区执行任何其他写入操作,因为这可能会使传递给 async_write 的底层内存块无效。
您可以做的只是使用 stringstream 来缓冲传入的数据,一旦挂起的异步写入完成,将内容刷新到 boost 流缓冲区并分派(dispatch)新的异步写入。当然,您可以使用更复杂的机制,例如维护一个流缓冲区池,以保留其状态信息(待处理或可用),并在每次调用 sendMessage 时从池中获取新的流缓冲区并分派(dispatch)新的异步写入。这完全取决于您的要求 - 吞吐量和延迟或内存消耗。

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

10-11 06:33
查看更多