2013-04-18 78 views
1

是否可以在同一个boost :: asio :: deadline_timer上多次调用async_wait?来自升压的多个async_wait asio deadline_timer

我的意思做的是类似如下:

t->expires_from_now(delay); 
t->async_wait(f1); 
t->async_wait(f2); 

这是否确保两个功能将被叫什么名字? 这是否确保这两个函数将按此顺序调用?

如果不是,有什么想法如何在定时器超时时连续调用f1和f2? (我不在乎是否在f1和f2的调用之间执行另一个处理程序)。

另一个问题:如果设置了两个定时器t1和t2,使t1的截止时间在t2的截止时间之前,我能确定与t1关联的处理程序将在与t2关联的处理程序之前被调用吗? (在这种情况下,对于上面的代码,我只会为f2创建一个第二个定时器,其延迟比为第一个定时器设置的延迟稍大)。

感谢

回答

6

仔细阅读文档上http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/basic_deadline_timer/async_wait.html,它指出

对于每个调用async_wait(),所提供的处理器将被调用正好一次

(强调我的)。这意味着在你的情况下,f1和f2都会被调用一次。

你的第二个问题:这取决于三个条件:

  1. 当到期时间仅相差系统时钟的分辨率低于短期内(或OS'es的时间可能有问题服务)。这种情况下的行为由定时器实现定义(但不应该成为Boost默认实现的问题,请参阅注释)。
  2. 多线程环境中两个处理程序可能的并发性。将两个处理程序包装到同一个链中,以避免出现与并发有关的问题。
  3. 取消定时器的可能性。当较早的定时器在较早的定时器到期之前被取消时(通过设置另一个到期时间),它在较早的定时器执行之前触发它的处理器。

更新:
我刚才意识到,有关于它的处理程序被调用的顺序中的第二部分你的第一个问题。文件没有提到任何有关的信息。你可以在执行过程中查看它,但这可能会改变。
如果您希望按顺序执行两个函数,只需从第一个函数调用第二个函数即可。如果第二个处理程序只能在某些情况下被“附加”到第一个处理程序,那么要么延迟调用async_wait,直到您知道处理程序链的整个范围,或者使它们彼此独立。
第三种可能性是推出自己的可追加处理程序。但请记住,处理程序会被复制到io_service::run线程中,即到async_wait调用中,所以可追加处理程序只需要一个指向真正处理程序链的指针,它将需要考虑并发性等。

+0

这是一个实现细节,但我认为第二个问题的第一点可能会有些不准确。 Boost.Asio在'timer_queue'中管理定时器操作,它们根据'Time_Traits :: less_than'排序。当反应堆从队列中删除准备好的计时器时,它将它们添加到'io_service'以进行延迟调用,它们应该按照时间顺序与系统时钟的分辨率无关。 –

+0

感谢您的关注。您可以像“实现定义”一样阅读答案的一部分 - 我给出的示例可能不适用于boost的计时器实现,但它们可能适用于其他自定义实现。我转述了答案的那部分 –

+0

听起来不错。处理程序的排序在['WaitableTimerService'](http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/WaitableTimerService.html)和['TimerService'](http ://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/TimerService.html)类型的要求。虽然['deadline_timer_service'](http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/deadline_timer_service.html)会按照时间顺序将它们排队,而与系统时钟的分辨率无关,不是必需的,并且定制服务可以以任何顺序安全地排队它们。 –