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

upd*_*liu 4 boost boost-asio

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

根据文件:

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

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

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

Tan*_*ury 5

文档:

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

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

发布到a strand中的所有处理程序都被认为是可以运行的.因此,strandAPI 缺乏完成条件.当strands与异步操作一起使用时,通常会为启动函数提供从以下返回的处理程序strand::wrap():

async_op(..., s.wrap(a));
Run Code Online (Sandbox Code Playgroud)

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

io_service与之关联的strand被破坏时,未被驱逐的处理程序被破坏.该文件规定:

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


要进入一些详细信息,一个链执行负责排队处理,保证只有其处理程序之一已张贴到io_service的时间,和strand只提供了一个公共API委托给链实现.每个strand都与链实现相关联,并且链实现可以与许多strands 相关联.这种关系允许许多不同对象共享单链实现strand.因此,文件备注:

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

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