Asio是“异步 IO操作”。asio::steady_timer是定时器。
io_context对象为异步IO对象提供核心功能。每个 Asio 程序都至少有一个 io_context对象。
run()是一个阻塞调用,所有的异步操作完成后,run()才返回。
下面程序空有 io_context
对象,却没有任何异步操作,所以run()直接就返回了。
int main()
{
asio::io_context ioc;
ioc.run();
return 0;
}
asio::steady_timer可以实现同步调用机制。
初始化时,第一个参数是asio::io_context,第二个参数设置定时器现在开始3秒后终止。
wait()是一个阻塞等待,3秒后定时器终止时返回。接着打印“Hello, world!”。
int main()
{
asio::io_context ioc;
asio::steady_timer timer(ioc, std::chrono::seconds(3));
timer.wait();
std::cout << "Hello, world!" << std::endl;
return 0;
}
asio::steady_timer也可以用来实现异步调用机制。
async_wait() 执行异步等待,设置回调函数Print,当异步操作结束后(此处即定时器结束后)该函数会被调用。
Asio保证回调句柄仅仅能被run()启动的当前线程所调用。如果run() 函数不执行,用于异步等待完成时的回调函数(此处即Print())将永远不会被调用。
void Print(std::error_code ec) {
std::cout << "Hello, world!" << std::endl;
}
int main()
{
asio::io_context ioc;
asio::steady_timer timer(ioc, std::chrono::seconds(3));
timer.async_wait(&Print);
ioc.run();
return 0;
}
下例中每隔1秒打印一次计数,从0到2。
async_wait回调函数的签名为 void (std::error_code)
,传递额外的参数时需要使用bind。
Print函数中,计数小于3时,expires_at()推迟定时器的终止时间。async_wait()启动一个新的异步等待。计数大于3时,run()函数返回。
void Print(std::error_code ec, asio::steady_timer* timer, int *count)
{
if (*count < 3)
{
std::cout << *count << std::endl;
++(*count);
timer->expires_at(timer->expires_at() + std::chrono::seconds(1));
timer->async_wait(std::bind(&Print, std::placeholders::_1, timer, count));
}
}
int main(int argc, char** argv)
{
asio::io_context ioc;
asio::steady_timer timer(ioc, std::chrono::seconds(3));
int count = 0;
timer.async_wait(std::bind(&Print,std::placeholders::_1, &timer, &count));
ioc.run();
return 0;
}