Timer.3 - Binding arguments to a handler
https://www.boost.org/doc/libs/1_74_0/doc/html/boost_asio/tutorial/tuttimer3.html
Timer.3 - Binding arguments to a handler
在本教程中,我们将接着改上篇教程Timer.2里的程序,这次我们将把计时器修改为每秒触发一次.并以此演示如何向我们的回调函数传参.
首先引入头文件,不解释
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
为了达到计时器每秒触发一次的目的,我们可以在每次计时结束时,在回调函数中给计时器的到期时间续一秒,让它再回去等着,如此往复.这样我们的计时器就可以反复去世了.很显然,要实现这个思路,我们需要在回调函数中拿到计时器的对象然后修改它.所以我们这次的 print 函数多加了两个参数:
- 指向计时器对象的指针
- 计数器, 记录触发次数, 够六次的时候让它停下来
void print(const boost::system::error_code& /*e*/,
boost::asio::steady_timer* t,
int* count)
{
就是这样(指下面的代码), 当触发第六次,也就是*count == 5的时候让他停下来.然而你会发现,我们并没有显式调用什么函数来手动让io_context停下来,为什么就能让他再起不能呢.回想一下,在上篇教程Timer.2里,我们说过io_context::run()这个函数是"有活干活儿, 没活儿完事"的.所以说,我们只要在count==5的时候,不再续计时器了, 这io_context没活干了,它自然就会停下来了.
if(*count < 5)
{
std::cout << *count << std::endl;
++(*count);
接下来我们给计时器续上一秒.因为我们是在上一次的到期时间上再续一秒,而不是再重新开一个一秒的计时,所以不用担心会把执行回调函数的误差时间给算进去.
t->expires_at(t->expiry() + boost::asio::chrono::seconds(1));
接下来就可以让计时器梅开二度了.如你所见,函数boost::bind可以给一个函数的某些参数事先"填坑",以此生成一个参数更少的函数对象.因为steady_timer::async_wait()内希望得到这样的函数/函数对象:void (const boost::system::error_code &). 所以我们先用boost::bind填上print函数后两个参数,转为只剩下的一个error_code类型参数的函数对象,这就能跟async_wait的需求完美对应了.
…实在不知道怎么翻译清楚了 以下是原文和直译
Then we start a new asynchronous wait on the timer.As you can see, the boost::bind() funct