来自async_resolve的boost :: asio :: ip :: tcp :: resolver :: iterator的生命周期是什么?

时间:2017-11-01 04:57:08

标签: c++ sockets boost tcp boost-asio

当我致电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?我是否必须做任何特殊的事情,或者只是让它们超出范围而不被任何回调闭合所持有?

(我知道我可以浏览resolver::entries处理程序中的所有async_resolve并将它们存储在智能结构或其他任何内容中,以便我控制它们的生命周期,但如果{{1已经在处理它了,如果我让它完成它的工作,我的代码会更简单。)

1 个答案:

答案 0 :(得分:2)

解构问题

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

我想你想知道迭代器的有效性

好的,the documentation shows迭代器类别为forward iterator。前向迭代器具有“多通道保证”,允许重复取消引用迭代器的副本,产生相同的结果¹。

所以,我们已经过了一半:保持迭代器仍然可以。但是,当然,与任何其他[forward]迭代器一样,我们必须考虑iterator invalidation

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

我们知道什么?

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

本着“按需付费”的精神,解决方案将状态保持在超过要求的时间是没有意义的。另一方面,如果不支持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 ++实现遵循 零开销原则:你不使用什么,你不支付[C ++的设计和演变,1994]

相关问题