Timer.2 使用异步定时器

Timer.2——使用异步定时器 #


原文链接 | 源码链接

本教程通过修改教程Timer.1中的程序,展示了如何使用asio的异步功能来对定时器进行异步等待。

#include <iostream>
#include <boost/asio.hpp>

使用 asio 的异步功能意味着提供一个 completion token,这个 token 决定了当异步操作完成时如何将结果传递到 completion handler。在这个程序中,我们定义了一个名为 print 的函数,该函数将在异步等待完成时调用。

void print(const boost::system::error_code& /*e*/)
{
  std::cout << "Hello, world!" << std::endl;
}

int main()
{
  boost::asio::io_context io;

  boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));

随后,我们不再像教程 Timer.1 那样执行阻塞等待,而是调用 steady_timer::async_wait() 函数来执行异步等待。调用该函数时,我们传递上面定义的 print 函数。

  t.async_wait(&print);

最后,我们必须调用 io_context 对象的 io_context::run() 成员函数。

asio 库保证 completion handlers 仅会被正在调用 io_context::run()的线程所调用。因此,除非调用了io_context::run()函数,否则异步等待完成的 completion handler 将永远不会被触发。

只要有“工作”要做,io_context::run() 函数就会继续运行。在这个例子中,“工作”是定时器中的异步等待,因此在定时器到期且 completion handler 返回之前,io_context::run() 将不会返回。

重要的是要记住在调用 io_context::run() 之前,给 io_context 一些要做的“工作”。例如,如果我们省略了上面对 stable_timer::async_wait() 的调用,则 io_context 没有任何工作要做,因此 io_context::run() 将立即返回。

  io.run();

  return 0;
}