gpt4 book ai didi

c++ - async_resolve 的 boost::asio::ip::tcp::resolver::iterator 的生命周期是多少?

转载 作者:可可西里 更新时间:2023-11-01 02:48:07 25 4
gpt4 key购买 nike

当我调用 boost::asio::ip::tcp::resolver::async_resolve 时,我的处理程序收到一个 ip::tcp::resolver::iterator 迭代一个或多个 ip::tcp::resolver::entries他们的生命周期是多少,让他们活着的把柄是什么?

例如,如果我得到第一个 entry 并向它启动一个 tcp::async_connect,那么在 async_connect 处理程序中,可以我迭代到下一个 entry 并启动另一个 async_connect 到下一个条目(只要我将 iterator 传递给 async_connect 处理程序,当然)?

什么时候清理 resolver::iteratorresolver::entries?我是否需要做任何特别的事情,或者只是让它们超出范围并且不被任何回调闭包保留?

(我知道我可以在我的 async_resolve 处理程序中运行所有 resolver::entries 并将它们存储在智能指向结构或其他任何东西中,这样我控制它们的生命周期,但如果 asio::ip::tcp::resolver 已经在处理它,如果我让它完成它的工作,我的代码会更简单。)

最佳答案

解构问题

迭代器具有值语义。因此它们的生命周期总是与周围对象的生命周期或它们的存储持续时间相关联(堆栈用于自动,堆用于动态,有时甚至是其他的,例如静态)。

我认为您想知道迭代器的有效性

嗯,the documentation shows迭代器类别是 forward iterator .前向迭代器具有“多次通过保证”,允许重复取消对迭代器拷贝的引用,从而产生相同的结果¹。

所以,我们已经完成了一半:保留迭代器仍然可以。然而,当然,就像任何其他 [forward] 迭代器一样,我们必须考虑 iterator invalidation .

因此,真正的问题归结为:解析器迭代器何时失效

我们知道什么?

resolve 函数实现的用例是连接。对于连接,第一个有效的端点就足够了,因此不需要它实际保留一个列表。

本着按需付费² 的 spirit ,解析器保持状态的时间超过所需时间是没有意义的。另一方面,如果不支持 Multipass,则将迭代器置于 ForwardIterator 类别中是没有意义的。

文档什么也没说。我们只有一种方法:深入研究代码

深入研究代码

我们发现表面以下的一些步骤:asio/detail/resolver_service.hpp:73

  // Asynchronously resolve a query to a list of entries.
template <typename Handler>
void async_resolve(implementation_type& impl,
const query_type& query, Handler& handler)
{
// Allocate and construct an operation to wrap the handler.
typedef resolve_op<Protocol, Handler> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
boost_asio_handler_alloc_helpers::allocate(
sizeof(op), handler), 0 };

resolve_op 显示迭代器是使用 basic_resolver_iterator.hpp::create 创建的

这让我们找到了答案:在 line 251

  typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type;
boost::asio::detail::shared_ptr<values_type> values_;
std::size_t index_;

因此,只要您保留有效迭代器(不是结束迭代器)的拷贝,您就可以继续取消引用它。它甚至会为每个解析器条目保留一份查询参数(host_nameservice_name)。这看起来有点浪费,但我想在设计缓存方案时会派上用场。

总结:

  • 问。解析器迭代器何时失效?
  • A.当有效迭代器的最后一个拷贝被销毁时。

翻译成“它们始终有效”(如果它们曾经有效的话)。


¹ 相对于例如输入迭代器

² 通常,C++ 实现遵循零开销原则:不使用的东西,你不支付 [The Design and Evolution of C++, 1994]

关于c++ - async_resolve 的 boost::asio::ip::tcp::resolver::iterator 的生命周期是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47048485/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com