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