asio计时器什么时候超出范围?

App*_*ood 7 c++ boost boost-asio

我的意思是,假设您在asio计时器上执行async_wait并将更新绑定到引用类型T的函数.假设您在将其传递给async_wait之前最初在堆栈上创建了T. 在async_wait结束时,它调用async_wait本身,反复更新计时器.该堆栈分配的类型T是否保持活动状态,直到定时器第一次不自行更新,或者在第一次调用该函数后T将超出范围?

sma*_*uck 10

如果您要编写一个在堆栈上创建定时器的函数,然后调用async_wait,则在函数调用结束时将销毁定时器,并使用正确的错误参数立即调用回调.

您无法使用boost :: bind将计时器对象传递给回调,因为该对象是不可复制的.

不过,您可以在堆上管理绑定器,在每次调用时将共享指针传递给async_wait.这看起来像这样:

void MyClass::addTimer(int milliseconds) // Initial timer creation call
{
  boost::shared_ptr<boost::asio::deadline_timer> t
    (new boost::asio::deadline_timer
     (m_io_service, 
      boost::posix_time::milliseconds(milliseconds)));
  // Timer object is being passed to the handler
  t->async_wait(boost::bind(&MyClass::handle_timer,
                            this,
                            t,
                            milliseconds));

}

void MyClass::handle_timer(boost::shared_ptr<boost::asio::deadline_timer> & t,
                               int milliseconds)
{
  // Push the expiry back using the same tick
  t->expires_at(t->expires_at() + boost::posix_time::milliseconds(milliseconds));
  t->async_wait(boost::bind(&MyClass::handle_timer,
                            this,
                            t,
                            milliseconds));
  onTimer(); // Do something useful
}
Run Code Online (Sandbox Code Playgroud)


jpy*_*man 1

我没有使用 asio 定时器的经验。但如果你这样做

void somefunc( void )
{
  boost::asio::io_service io;

  boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
}
Run Code Online (Sandbox Code Playgroud)

那么当定时器退出函数时就超出了范围。所以使用这段代码就不会发生等待。如果将 t.wait() 添加到该代码中,它将等待 5 秒并退出该函数,并且计时器超出范围。

void somefunc( void )
{
  boost::asio::io_service io;

  boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
  t.async_wait(somecallback);

  io.run();
}
Run Code Online (Sandbox Code Playgroud)

在第二个示例中,当函数退出时,计时器超出范围。

如果你想循环定时器我想你必须这样写。

void somefunc( void )
{
  boost::asio::io_service io;

  while( something )
  {
    boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
    t.async_wait(somecallback);

    io.run();
  }
}
Run Code Online (Sandbox Code Playgroud)

这将使计时器在循环中在堆栈上保留一圈,然后重新创建它。如果将计时器放在循环之外,它将永远不会超出范围。但随后你必须以某种方式在循环中重置它。但我没有看到任何这样的功能。

编辑:在 async_wait() 的示例中,如果没有 io.run() 使其等待,计时器将直接被销毁,超出范围,而不会完成。我猜想,deadline_timer() 的析构函数会在计时器命中析构函数时取消计时器。