boost async_wait()会导致新线程吗?

时间:2014-06-09 20:21:05

标签: c++ boost boost-asio boost-thread

我们需要经常调用一个方法来进行一些计算(大约每秒20次)。这是一个同步通话。调用者需要尽快得到结果。但有时候,计算过程需要比预期更长的时间。我们不想改变其他任何内容。我们只想添加一种监控机制来标记应用程序当超出预期的时间段时当前计算超时。

我们现在有两种选择:

选项1:

在课程级别创建一个监控线程,并且将在应用程序的整个生命周期中继续运行。无论何时调用计算方法,它都会开始监视计算方法的性能。它将在返回呼叫时重置:

   monitorThread.startMonitoring();
   doComputation();
   monitorThread.stopMonitoring();

当调用startMonitoring()时,working标志将设置为true,并且开始时间将设置为该monitorThread上的当前时间。当它唤醒时,它将能够知道当前条件是否超时。

当调用stopMonitoring()时,working标志将被设置为false,而monitorThread将不会检查超时。

选项2:

使用 boost deadline_timer

boost::asio::deadline_timer timer(io_service);
timer.expires_from_now(boost::posix_time::seconds(1));
timer.async_wait(handler);
doComputation();
timer.cancel();

我不确定dateline_timer选项是否适用于我们:

  1. 我可以在类级别定义计时器并在应用程序的整个运行会话期间重用它吗?
  2. async_wait()调用是否会在后台生成一个新线程?如果是的话,可以一次又一次地重用该线程吗?
  3. 修改

    1。 如果我在方法体中使用以下代码,则处理程序将由当前线程调用,而doComputation()也在同一线程中运行。在 doComputation ()挂起的情况下,如何调用处理程序

    boost::asio::deadline_timer timer(io_service);
    timer.expires_from_now(boost::posix_time::seconds(1));
    timer.async_wait(handler);
    io_service.run(); // new added
    doComputation();  // <<---- may hung sometime
    timer.cancel();
    

    2。 为了重用计时器并最小化线程数。我应该在开始时实例化 io_service ,即将boost::asio::deadline_timer timer(io_service);放在构造函数中。并且还在一个新的专用线程中调用io_service.run();(并在通话后让它死掉)?或者只是在init主线程中调用它,因为 io_service.run()无论如何都会启动一个新线程?在使用计时器的地方,以下代码就足够了:

    timer.cancel();
    timer.expires_from_now(boost::posix_time::seconds(1));
    timer.async_wait(handler);
    doComputation();  // <<---- may hung sometime
    timer.cancel();
    

    我是对的吗?

1 个答案:

答案 0 :(得分:3)

  

我可以在类级别定义计时器并在整个过程中重复使用它   运行会话的应用程序?

是的,您可以重新使用计时器,即再次拨打expires_from_now()async_wait()(但请阅读参考资料以了解他们的行为!)。

  

async_wait()调用是否会导致新的线程   背景?如果是的话,是否可以再次重用该线程   再次?

否(但无论如何都是实施细节)。 handler将在运行io_service::run()的线程中调用。

关注编辑

  1. 强烈建议您查看Asio documentation。请注意io_service::run()阻止调用 - 它会阻塞,直到调用所有完成处理程序。您可以将其视为&#34;消息循环&#34;。通常,从专用线程调用它。或者,可以手动轮询io_service,在其他特定于应用程序的循环中调用poll()/poll_one()

  2. io_service :: run()在没有更多工作时返回,即没有待处理的异步操作,也没有要调度的完成处理程序。为了保持这个&#34;消息循环&#34;在您的模块的整个生命周期内运行(以便您可以随时发出异步操作),您需要associate io_service::work objectio_service