如果调用asio::strand
的析构函数时,该链上仍有一些准备好/未准备好的处理程序?
根据文件:
通过链发布的处理程序尚未被调用 仍然以符合保证的方式派遣 非并发性。
这是否意味着它仍将调用所有处理程序,包括等待未准备好的处理程序准备就绪,就好像它没有被销毁一样(可能除了不接受新的处理程序)?
或许我在概念上错误地认为“unready handler”---异步操作在完成之前不会在其上发布其处理程序?如果调用目标链的析构函数,这个异步操作是否会意识到这一点?
答案 0 :(得分:5)
通过
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
的生命周期。被包裹着。