boos库中asio定时器使用示例

官网参考示例:

https://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/

这个是/async_tcp_client示例:

https://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/timeouts/async_tcp_client.cpp

 

 

原文:http://www.voidcn.com/article/p-efmozrnt-bex.html

异步定时器 和 同步定时器,简单示例:

#include <iostream> 
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/function.hpp> 
#include <boost/bind.hpp>
#include <time.h>

#include <boost/functional.hpp>//可调用实体对象

using std::cout;
using std::endl;
using boost::asio::io_service;
using boost::asio::deadline_timer;
using std::bind;
using std::function;
using boost::posix_time::millisec;
using boost::posix_time::microsec;

//同步定时器
void test1()
{
    io_service ios;//所有的asio程序必须要有一个io_service对象
    deadline_timer t(ios,boost::posix_time::seconds(5));//5秒钟后定时器终止
    float start_t = clock();
    
    cout<<t.expires_at()<<endl;//查看终止的决定时间

    cout<< "time_start = "<< clock()<<endl;
    
    t.wait();//调用wait()同步等待 ----------------------此处阻塞

    cout<< "time_end= "<< clock()<<endl;
    cout<< "time_use = "<< (clock()-start_t)/CLOCKS_PER_SEC<<endl;
    cout<<"hello asio"<<endl;

/*
可以把它与thread库的sleep()函数对比研究一下,两种虽然都是等待,但内部机制完全不同:
thread库的sleep()使用了互斥量和条件变量,在线程中等待,而asio则是调用了操作系统的异步机制,
如select,epool等完成。
   同步定时器的用法很简单,但它演示了asio程序的基本结构和流程:
一个asio程序首先要定义一个io_service对象,它是前摄器模式中最重的proactor角色,
然后我们声明一个IO操作(这里是定时器),并把它挂接在io_service上,
再然后就可以执行后续的 同步或异步操作。
*/
}


/*
   异步定时器:代码大致与同步定时器相同,增加了回调函数,
   并使用io_service_run()和定时器的async_wait()
  首先我们要定义回调函数,asio库要求回调函数只能有一个参数,
  而且这个参数必须是const asio::error_code&类型

*/


void myprint(boost::system::error_code ec)
{    
    for(int i=0;i<5;i++)
        cout<<"hello asio"<<endl;
    
}
void test2()
{
    io_service ios;
    deadline_timer t(ios,boost::posix_time::seconds(3));

    t.async_wait(myprint);//异步等待,传入回调函数,立即返回
    cout<<"it show before t expired."<<endl;
    ios.run();//很重要,异步IO必须  ----------------------此处阻塞,保证
    cout<<"runned"<<endl;//将与hello asio一起输出,说明run()是阻塞函数

/* 
异步等待async_wait(),它通知io_service异步的执行IO操作,
用于在IO操作完成时有事件多路分离器分派返回值(error_code)调用。
最后我们必须调用io_service的run()成员函数,它启动前摄器的事件处理循环,
阻塞等待所有的操作完成并分派事件。如果不调用run()那么虽然被异步执行了,
但没有一个等待他完成的机制,回调函数将得不到执行的机会。
*/
}

    一个可以定时执行任意函数的定时器类 a_timer(asyc timer),它持有一个asio定时器对象和一个计数器,还有一个function对象用来保存回调函数;如下:

class a_timer
{
    private:
        int count,cout_max; //计数器成员变量
        function<void()> f; //function对象,持有无参数无返回的可调用实体
        deadline_timer t;//asio定时器
    public:

/*
构造函数初始化成员变量,将计数器清理,设置计数器的上限,拷贝存储回调函数,
并立即启动定时器之所以要"立即"启动,是因为我们必须包装在io_service.run()之前,
至少有一个异步操作在执行,否则io_service.run()会因为没有事件处理而立即不等待返回。
*/
        //模板类型,可接受任意可调用物
        template<typename F> a_timer(io_service& ios,int x,F func):f(func),
cout_max(x),count(0),t(ios,microsec(500))
        {
            t.async_wait(bind(&a_timer::call_func,this,std::placeholders::_1));
/*
占位符_1,_2,用于传递errror_code值。
bind(&a_timer::call_func,this,std::placeholders::_1)将 传递进去的函数,绑定到this指针,
返回一个可调用实体
*/

        
        }

//call_func()内部累加计数器,如果计数器未达到上限则调用function对象f,
//然后重新设置定时器的终止时间,再次异步等待被调用,从而达到反复执行的目的。
        void call_func(const boost::system::error_code &)
        {
            if(count >= cout_max)
            {
                return;
            }
            ++count;
            f();//外部要执行的函数
            t.expires_at(t.expires_at()+millisec(500));
//设置定时器的终止时间为0.5秒之后 
// 重新设定计时器终止时间,使得可以可以一直执行下去,直到终止条件触发;
            t.async_wait(bind(&a_timer::call_func,this,std::placeholders::_1));
        }
};
void print1(int index)
{
    cout<<"hello asio:"<<index<<endl;
}
void print2()
{
    cout<<"hello boost *********** "<<endl;
    cout<<"hello boost *********** "<<endl;
    cout<<"hello boost *********** "<<endl;
    cout<<"hello boost *********** "<<endl;
    cout<<"hello boost *********** "<<endl;
    cout<<"hello boost *********** "<<endl;
}
void test3()
{
    io_service ios;    
    a_timer a(ios,5,std::bind(print1,2));//启用第一个定时器
    a_timer at(ios,3,print2);//启用第二个定时器
    ios.run();//ios等待异步调用结束
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值