简体   繁体   English

如何重启升压截止时间计时器

[英]How to restart boost deadline timer

I have a requirement such that my timer must be reset based on 2 conditions, whichever happens earlier. 我有一个要求,我的计时器必须根据2个条件(无论哪个较早发生)进行重置。

  1. When timer expires 计时器到期时
  2. When certain condition is met (like memory reaches certain limit) 当满足特定条件时(例如内存达到特定限制)

I am following these steps: 我正在按照以下步骤操作:

boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(1));
boost::mutex mtx1;

void run_io_service()
{
    io.run();
}

void print(const boost::system::error_code& /*e*/)
{
    boost::mutex::scoped_lock lock(mtx1);
    std::cout << "Hello, world!\n";
    t.expires_from_now(boost::posix_time::seconds(1));
    t.async_wait(print);
    std::cout << "Print executed\n";
}
int main()
{
    t.async_wait(print);
    boost::thread monitoring_thread = boost::thread(run_io_service);
    boost::this_thread::sleep( boost::posix_time::seconds(2));
    t.cancel();
    std::cout << "Resetting Timer\n";
    t.async_wait(print);
    boost::this_thread::sleep( boost::posix_time::seconds(2));
    t.cancel();
    io.stop();
    monitoring_thread.join();
    return 0;
}

This code works fine till the time timer hasn't been cancelled. 在未取消计时器之前,该代码可以正常工作。 Once timer has been cancelled, timer doesn't work in expected way , it doesn't work at all. 取消计时器后,计时器将无法按预期方式工作 ,也将完全无法工作。

What am I doing wrong? 我究竟做错了什么?

The first problem is that the handler will still be called if there is an error (such as it being cancelled), you need to check the error code. 第一个问题是,如果有错误(例如已取消),处理程序仍将被调用,您需要检查错误代码。

void print(const boost::system::error_code& e )
{
    if( e ) return; // we were cancelled
    // actual error code for cancelled is boost::asio::error::operation_aborted

    boost::mutex::scoped_lock lock(mtx1);
    std::cout << "Hello, world!\n";
    t.expires_from_now(boost::posix_time::seconds(1));
    t.async_wait(print);
    std::cout << "Print executed\n";
}

Secondly, when you cancel the timer, that leaves the io_service object without any work, which means the run_io_service thread will terminate and leave you without service. 其次,当您取消计时器时,io_service对象将不做任何工作,这意味着run_io_service线程将终止并为您服务。 To keep the service alive during the whole program, give it a work object at the start of main: 为了使服务在整个程序中保持活动状态,请在main开始时为其提供一个工作对象:

int main() {
    boost::asio::io_service::work work(io);
    ...

And.. as mentioned by sehe, you are not handling the timer safely (or std::cout). 和..如sehe所述,您没有安全地处理计时器(或std :: cout)。 You should be locking mtx1 when you print the reset message and reset the timer, otherwise Murphy's law dictates that it may occur at the exact moment the handler is running and mess things up. 当您打印重置消息并重置计时器时,您应该锁定mtx1,否则,墨菲定律指示它可能在处理程序运行的确切时刻发生并弄乱事情。

You need to set a new expiration. 您需要设置一个新的到期时间。

In fact, you don't have to explicitly cancel in this event, because setting a new experation implicitly cancels any pending async wait. 实际上,您不必在此事件中显式取消,因为设置新的Experation会隐式取消任何未决的异步等待。

Keep in mind that the deadline_timer object itself is not thread safe though, so you will need to keep your timer mutations synchronized. 请记住,deadline_timer对象本身不是线程安全的,因此您将需要使计时器突变保持同步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM