如何重新启动升压截止计时器

gar*_*721 2 c++ boost-asio

我有一个要求,我的计时器必须根据两个条件重置,以较早发生的为准。

  1. 当定时器到期时
  2. 当满足一定条件时(比如内存达到一定限制)

我正在执行以下步骤:

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;
}
Run Code Online (Sandbox Code Playgroud)

这段代码可以正常工作,直到计时器没有被取消。 一旦定时器被取消,定时器就不会以预期的方式工作,它根本就不会工作。

我究竟做错了什么?

muk*_*nda 5

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

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";
}
Run Code Online (Sandbox Code Playgroud)

其次,当您取消计时器时,io_service 对象将不再执行任何工作,这意味着 run_io_service 线程将终止并让您无法获得服务。为了使服务在整个程序中保持活动状态,请在 main 开始时给它一个工作对象:

int main() {
    boost::asio::io_service::work work(io);
    ...
Run Code Online (Sandbox Code Playgroud)

而且..正如 sehe 提到的,您没有安全地处理计时器(或 std::cout)。当您打印重置消息并重置计时器时,您应该锁定 mtx1,否则墨菲定律规定它可能会在处理程序运行时发生并弄乱事情。