【问题标题】:When does an asio timer go out of scope?asio 计时器何时超出范围?
【发布时间】:2010-03-13 01:59:04
【问题描述】:

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

【问题讨论】:

  • 如果你能更好地解释你想如何使用 async_wait() 那就太好了。也许通过一些代码或元代码。您可能需要像 small_ducks 回答那样做,并使用 new 创建计时器以将其传递给其他函数并获得您想要的效果。

标签: c++ boost boost-asio


【解决方案1】:

如果您要编写一个函数,在该函数中在堆栈上创建一个计时器,然后调用 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
}

【讨论】:

    【解决方案2】:

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

    void somefunc( void )
    {
      boost::asio::io_service io;
    
      boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
    }
    

    那么定时器在退出函数时就超出了作用域。因此,使用此代码无需等待。如果您将 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();
    }
    

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

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

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

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

    编辑:在 async_wait() 的例子中,如果你没有 io.run() 让它等待,计时器将被销毁,超出范围,直接没有完成。而且我猜deadline_timer()的析构函数会在遇到析构函数时取消计时器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      • 2015-02-04
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 2014-06-18
      • 1970-01-01
      相关资源
      最近更新 更多