Когда asio таймер выходит из объема?

То, что я имею в виду, скажем, Вы делаете async_wait на asio таймере и связываете обновление функции, которая берет ссылку на тип T. Скажем, Вы создали T первоначально на стеке прежде, чем передать его async_wait. В конце этого async_wait это называет сам async_wait, возобновляя таймер много раз. Это складывает выделенный тип T, остаются в живых до первого раза таймер не возобновляет себя, или после того, как первый вызов функции будет T выходить из объема?

7
задан NmdMystery 12 January 2014 в 19:54
поделиться

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

Это сохранит таймер в стеке на один оборот в цикле, а затем он будет создан заново. Если вы поместите таймер за пределы цикла, он никогда не выйдет из области видимости. Но тогда вам придется каким-то образом сбрасывать его каждый оборот цикла. Но я не вижу такой функции.

EDIT: В примере с async_wait() таймер будет уничтожен вне области видимости, непосредственно без завершения, если у вас нет io.run(), чтобы заставить его ждать. И я бы предположил, что деструктор deadline_timer() сделает отмену таймера, когда он попадет в деструктор.

1
ответ дан 6 December 2019 в 23:04
поделиться

Если написать функцию, в которой создать таймер на стеке, а затем вызвать 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
}
10
ответ дан 6 December 2019 в 23:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: