考虑以下代码:
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/