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

时间:2014-11-24 07:43:08

标签: c++ boost-asio

我的要求是必须根据2个条件重置我的计时器,以先发生者为准。

  1. 当计时器到期时
  2. 当满足某些条件时(如内存达到一定限度)
  3. 我正在遵循以下步骤:

    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;
    }
    

    此代码正常工作,直到时间计时器尚未取消。 一旦取消定时器,定时器无法按预期方式工作,它根本不起作用。

    我做错了什么?

2 个答案:

答案 0 :(得分:3)

第一个问题是,如果出现错误(例如被取消),仍会调用处理程序,您需要检查错误代码。

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";
}

其次,当你取消定时器时,io_service对象没有任何工作,这意味着run_io_service线程将终止并让你没有服务。要在整个程序期间保持服务的活跃性,请在main的开头给它一个工作对象:

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

并且......如上所述,您没有安全地处理计时器(或std :: cout)。当您打印重置消息并重置计时器时,您应该锁定mtx1,否则Murphy的法律规定它可能发生在处理程序运行的确切时刻并且搞乱了。

答案 1 :(得分:2)

您需要设置新的到期日期。

事实上,您不必在此事件中明确取消,因为设置新的操作会隐式取消任何待处理的异步等待。

请记住,deadline_timer对象本身并不是线程安全的,因此您需要保持计时器突变的同步。