• 【Boost】boost库中timer定时器 1


    博客转载自:http://blog.csdn.net/liujiayu2/article/details/50384537

    同步Timer

    asio中提供的timer名为deadline_timer,它提供了超时计时的功能。首先以一个最简单的同步Timer为例来演示如何使用它。

     #include <iostream>
     #include <boost/asio.hpp>
    
     int main()
     {
        boost::asio::io_service io;
        boost::asio::deadline_timer timer(io, boost::posix_time::seconds(3));
        
        timer.wait();
        std::cout << "Hello, world!
    ";
        return 0;
    }

    首先常见了一个io_service对象,它提供了IO调度功能,asio库中的所有io操作都是基于它来执行的。然后创建了一个deadline_timer对象,它有两个参数,一个是io_service对象,另一个是超时时间。

    创建了timer后,就可以调用wait函数来阻塞等待至timer超时了,它还有一种可以指定错误码的入参的重载形式,关于错误码后面再介绍。

    异步Timer

    同步timer虽然简单,但由于其会阻塞,在实际的项目中并不常用,而往往使用的是异步timer:指定一个回调函数,计时器超时后执行回调函数。asio中实现异步timer比较简单,示例如下:

    void print(const boost::system::error_code& /*e*/)
    {
        std::cout << "Hello, world!
    ";
    }
    
    int main()
    {
        boost::asio::io_service io;
        boost::asio::deadline_timer timer(io, boost::posix_time::seconds(5));
    
        timer.async_wait(&print);
        io.run();
    
        return 0;
    }

    和同步方式相比,它主要有两点不同:

    1. 调用的是非阻塞函数async_wait,它的入参是一个回调函数。
    2. 显式调用io_service.run()函数驱动异步IO调度。

    取消Timer

    void print(const boost::system::error_code& err)
        {
            if(err)
            {
                std::cout << "timer is canceled
    ";
                return;
            }
    
            std::cout << "Hello, world!
    ";
        }
    
        int main()
        {
            boost::asio::io_service io;
    
            boost::asio::deadline_timer timer(io, boost::posix_time::seconds(5));
            timer.async_wait(&print);
    
            boost::asio::deadline_timer timer2(io, boost::posix_time::seconds(2));
            timer2.wait();
            timer.cancel();
    
            io.run();
            return 0;
        }

    更改Timer超时时间

    可以通过expires_from_now和expires_at两个函数更改Timer的超时时间,如下示例就通过它实现一个周期计时器。

    Timer还有一种常用操作是取消Timer,基本方法如下:

    1. 调用timer的cancel函数取消timer
    2. timer取消后,回调函数会立即执行,通过err_code可以感知到计时器是否已经被取消
    typedef std::function<void (const boost::system::error_code&)> timer_callback ;
        void print(const boost::system::error_code&)
        {
            std::cout << "Hello, world!
    ";
        }
    
        int main()
        {
            boost::asio::io_service io;
            boost::asio::deadline_timer timer(io, boost::posix_time::seconds(1));
    
            timer_callback callback = [&](const boost::system::error_code& err) 
            {
                print(err);
                timer.expires_at(timer.expires_at() + boost::posix_time::seconds(1));
                timer.async_wait(callback);
            };
    
            timer.async_wait(callback);
            io.run();
            return 0;
        }

    //

    #include <iostream>  
    #include <boost/asio.hpp>  
    #include <boost/bind.hpp>  
    #include <boost/date_time/posix_time/posix_time.hpp>  
      
    class printer  
    {  
    public:  
      printer(boost::asio::io_service& io)  
        : timer_(io, boost::posix_time::seconds(1)),  
          count_(0)  
      {  
        timer_.async_wait(boost::bind(&printer::print, this));  
      }  
      
      ~printer()  
      {  
        std::cout << "Final count is " << count_ << "
    ";  
      }  
      
      void print()  
      {  
        if (count_ < 5)  
        {  
          std::cout << count_ << "
    ";  
          ++count_;  
      
          timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1));  
          timer_.async_wait(boost::bind(&printer::print, this));  
        }  
      }  
      
    private:  
      boost::asio::deadline_timer timer_;  
      int count_;  
    };  
      
    int main()  
    {  
      boost::asio::io_service io;  
      printer p(io);  
      io.run();  
      
      return 0;  
    }  

    //

    #include <iostream>  
    #include <time.h>  
    #include <boost/asio.hpp>  
    #include <boost/bind.hpp>    
    #include <boost/function.hpp>  
    #include <boost/date_time/posix_time/posix_time.hpp>    
      
    using namespace std;  
      
    //超时控制器类  
    class TimerController   
    {  
    public:  
      
        /** 
         * 超时控制器构造函数 
         * @param ios 异步I/O对象 
         * @param callbackFunc 超时处理回调函数 
         * @param uiWaitSec 定时器间隔等待时间,单位:秒 
         */  
        explicit TimerController(boost::asio::io_service &ios, boost::function<void()> callbackFunc, unsigned int uiWaitSec) :  
                m_timer(ios, boost::posix_time::seconds(3))   
        {  
            cout<< "1111111111111" << "-----" << time(NULL)<<endl;  
            m_timeoutHandle = callbackFunc;  
            m_uiWaitSec = uiWaitSec;  
            m_timer.async_wait(boost::bind(&TimerController::onTime, this, boost::asio::placeholders::error));  
        }  
      
        /** 
         * 析构函数 
         */  
        ~TimerController()   
        {  
            m_timer.cancel();  
        }  
      
        /** 
         * 定时器响应函数 
         * @param error_code 定时器异常错误信息 
         */  
        void onTime(const boost::system::error_code&)   
        {  
            m_timeoutHandle();  
            m_timer.expires_at(m_timer.expires_at() + boost::posix_time::seconds(1));  
            m_timer.async_wait(boost::bind(&TimerController::onTime, this, boost::asio::placeholders::error));  
        }  
      
    private:  
        unsigned int                    m_uiWaitSec;                //定时间间隔等待时间  
        boost::asio::deadline_timer     m_timer;                    //asio定时器  
        boost::function<void()>           m_timeoutHandle;            //超时处理回调函数  
    };  
      
      
    //构造函数  
    class CmdQueueManager  
    {  
    public:  
        CmdQueueManager(boost::asio::io_service* io)  
        {  
            m_pTimer     = new TimerController(*io,boost::bind(&CmdQueueManager::SendProcess, this),1);  
        }  
          
        void SendProcess()  
        {  
            cout<< "1111111111111" << "-----" << time(NULL)<<endl;  
        }  
          
        TimerController *               m_pTimer;  
    };  
      
    int main()   
    {  
        boost::asio::io_service io;  
          
        CmdQueueManager t(&io);  
        io.run();  
          
        return 0;  
    } 

    最近做项目时,做了一个定时器,发现定时器回调函数不按照指定时间回调,总是延迟,后经研究发现,是IO出了问题,把一个IO绑定到多个socket上面,并把这个IO绑定到定时器上面,有一些socket连接网络时发出了一些connect行为,这些行为会造成IO阻塞,当然这只是猜测,看到的读者可以帮忙讲解一下。所以本人建议做timer时候,自建一个人“干净”的IO。

  • 相关阅读:
    自定义能够for each的类,C#,Java,C++,C++/cli的实现方法
    答网友强护灰飞烟灭关于接口的问题
    浅谈C++的this指针
    padding与margin的区别(网上转的)
    啦啦啦 刚注册的,先水一篇~
    直接把页面的table导出到excel表中
    从FTP下载文件带进度条
    C# 从FTP上下载指定文件到本机
    “无法在证书存储区中找到清单签名证书”错误的解决方法
    网页设置不可复制
  • 原文地址:https://www.cnblogs.com/flyinggod/p/8324396.html
Copyright © 2020-2023  润新知