如果调用asio :: strand的析构函数时,该链上仍有一些就绪/未准备好的处理程序?

时间:2014-05-23 06:29:30

标签: boost boost-asio

如果调用asio::strand的析构函数时,该链上仍有一些准备好/未准备好的处理程序?

根据文件:

  

通过链发布的处理程序尚未被调用   仍然以符合保证的方式派遣   非并发性。

这是否意味着它仍将调用所有处理程序,包括等待未准备好的处理程序准备就绪,就好像它没有被销毁一样(可能除了不接受新的处理程序)?

或许我在概念上错误地认为“unready handler”---异步操作在完成之前不会在其上发布其处理程序?如果调用目标链的析构函数,这个异步操作是否会意识到这一点?

1 个答案:

答案 0 :(得分:5)

来自documentation

  

通过strand发布的尚未调用的处理程序仍将以满足非并发保证的方式进行调度。

基本上,strand可以被认为是与处理程序队列相关联但不拥有的。如果处理程序队列当前没有发布到io_service的处理程序,那么它将从其自身弹出一个处理程序并将其发布到关联的io_service中。此流程可确保不会同时调用发布到同一strand的处理程序。

发布到strand的所有处理程序都被认为是可以运行的。因此,strand API缺乏完成条件。当strand与异步操作一起使用时, initiating function 通常会提供从strand::wrap()返回的处理程序

async_op(..., s.wrap(a));

完成async_op()后,它将调用从s.wrap(a)返回的处理程序。然后,此处理程序将用户提供的处理程序a发布到与原始strand链相同的队列关联的s中。由于strand对象的生命周期不会影响处理程序队列的生命周期,async_op()不需要关注s的生命周期。

当与io_service关联的strand被销毁时,未被驱逐的处理程序将被销毁。 documentation州:

  

计划在io_service或任何关联的strand上延迟调用的未调用处理程序对象将被销毁。


为了更详细一点, strand实现负责排队处理程序,并保证其中只有一个处理程序一次发布到io_service,并且strand仅提供委托给 strand实现的公共API。每个strand链实现相关联,链实现可以与许多strand相关联。这种关系允许单个链实现由许多不同的strand对象共享。因此,文档remarks

  

该实现不保证将同时调用通过不同strand对象发布或分派的处理程序。

Boost.Asio控制这些 strand实现的生命周期,并懒惰地在 strand implementation 的固定大小池中分配它们。可以通过将BOOST_ASIO_STRAND_IMPLEMENTATIONS定义为所需的数字来配置池的大小。由于strand对象的生命周期不会影响 strand实现的生命周期,因此异步操作不需要关心处理程序中strand的生命周期。被包裹着。