【问题标题】:boost async_wait() will cause a new thread?boost async_wait() 会导致一个新线程吗?
【发布时间】:2014-06-09 20:21:04
【问题描述】:

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

我们现在有两个选择:

选项 1:

在类级别创建一个监控线程,它将在应用程序的整个生命周期内保持运行。每当调用该计算方法时,它将开始监视该计算方法的性能。调用返回时会重置:

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

调用 startMonitoring() 时,working 标志将设置为 true,并且开始时间将设置为该 monitorThread 上的当前时间。唤醒时就可以知道当前状态是否超时。

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

选项 2:

使用提升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() 调用会在后台产生一个新线程吗?如果是,是否可以一次又一次地重用该线程?

编辑:

1。 如果我在方法主体中使用以下代码,则处理程序将由当前线程调用,并且 doComputation() 也会在同一线程中运行。 doComputation()挂起的情况下,handler是怎么调用的?

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();(并在调用后让它死掉)?或者只是在初始化主线程中调用它,因为 io_service.run() 无论如何都会启动一个新线程?在使用定时器的地方,下面这段代码就足够了:

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

我说的对吗?

【问题讨论】:

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


    【解决方案1】:

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

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

    async_wait() 调用是否会在 背景?如果是,是否可以再次重用该线程并且 再来一次?

    否(但无论如何这是一个实现细节)。 handler 将从运行 io_service::run() 的线程中调用。

    按照您的编辑

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

    2. io_service::run() 在没有更多工作时返回,即没有挂起的异步操作和完成处理程序要分派。为了在模块的整个生命周期内保持这个“消息循环”运行(这样你就可以随时发出异步操作),你需要 associate io_service::work objectio_service

    【讨论】:

    • 这意味着我必须调用 io_service::run() 每次都会触发一个新线程?
    • @5YrsLaterDBA 为什么每次都是新线程?通常,在一个线程中运行io_service::run(),用于整个应用程序(或模块)的生命周期。然后你可以将这个io_service 用于任意数量的 Asio 对象(定时器、套接字等)。
    • 能帮我更多吗?我在上面的编辑部分添加了更多内容。我仍然对计时器的工作方式有些困惑。
    • @5YrsLaterDBA 我已经更新了答案,但请阅读基本的 Asio 教程并查看overview
    猜你喜欢
    • 2020-08-29
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 2020-06-18
    • 1970-01-01
    相关资源
    最近更新 更多