最后几天,我大量阅读了asio示例以及关于SO的其他问题,这些问题与传递给asios启动函数的缓冲区的生命周期管理有关。让我印象深刻的一个问题是,似乎没有“按值”解决方案,但是初始化函数的调用者始终需要确保缓冲区有效,直到异步操作完成为止。通常,这是通过创建指向数据的共享指针并将其复制到处理程序中来实现的。
就我而言,我已经在使用async_write
重载了,传递了ConstBufferSequence
并保存了例如下一条消息的大小,然后是下一条消息。即
auto message = std::make_shared<std::string>("hello");
auto size = std::make_shared<std::uint32_t>(message.size());
std::vector<asio::const_buffer> buffers = {asio::buffer(size, sizeof(*size)), asio::buffer(*message)};
asio::async_write(_socket, buffers, [message,size](...){...}); // prolong lifetime by coping shared ptrs.
因此,我正在考虑编写一个自定义Message
类,该类既可以满足ConstBufferSequence
概念,又可以让拥有基础消息。我仔细研究了一下代码,发现在某个地方,首先通过asio::async_write
传递到const&
的缓冲区序列参数通过const&
传递,直到最终被复制到asio::detail::write_op
类的成员变量中。所以这里是实际的问题:
asio::async_write(_socket, Message("hello"),[](auto,auto){});
对您的想法感到好奇-欢迎批评! ;-)
问候,马丁
最佳答案
我之前看过shared_buffer
(我认为它在Asio docs / exmples中,稍后会搜索)。
此外,显然有
当然,它只是将问题从所有权问题转移到生命周期问题。
将Boost Asio的缓冲区概念设为“仅引用”或“ View 语义”的好处是
找到了Asio示例:https://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/example/buffers/reference_counted.cpp这些天住在
解决项目符号
Can this approach work for a fire and forget call? This would translate above intos something like: asio::async_write(_socket, Message("hello"),{});
是
Are there any issues with the lifetime of the constbuffer sequence arguments w.r.t. composed operations?
如果您管理得好,那就不是,这仍然是要求
Would this be a good idea? It obviously goes against the "normal" asio way of dealing with buffer lifetime management.
取决于您的操作方式。如果最终复制批发的缓冲区,那将是昂贵的,并且也将无法使用某些异步操作(这要求缓冲区具有引用稳定性,这意味着:不要更改地址,换句话说,不要四处走动)。
通过移动语义可以使许多缓冲区类型仍然能够提供此属性,但是按值传递缓冲区的问题是它们可能会创建多个副本,
关于c++ - 拥有 `ConstBufferSequence`的boost::asio数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62599431/