• 使用boost的deadline_timer实现一个异步定时器


    概述

    最近在工作上需要用到定时器,然后看到boost里面的deadline_timer可以实现一个定时器,所以就直接将其封装成了ATimer类,方便使用,ATimer有以下优点:

    1. 可以支持纳秒、毫秒、秒、分、小时定时。
    2. 可以随时停止定时器。
    3. 支持单次调用。
    4. 因为使用了deadline_timer,所以定时比较准确。

    ATimer和Qt的QTimer使用方法类似,若没有类似的Timer类,使用最原始的方法,我们的代码可能会是这样的:

    m_timerThread = std::thread([this]
    {
    	while (!m_bThreadStoped)
    	{
    		++m_sleepCount;
    		Sleep(SLEEP_DURATION_TIME);
    
    		if (m_sleepCount == m_sleepAllCount)
    		{
    			m_sleepCount = 0;
    			doSomeThing();
    		}
    	}
    });
    

    若使用QTimer的话,书写是这样的:

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    timer->start(1000);
    

    再来看看ATimer的使用:

    ATimer<> t;
    t.bind([]{ std::cout << "Hello C++" << std::endl; });
    t.start(1000);
    

    从上面的例子可以看到,QTimer和ATimer的使用都非常方便,接下来看看ATimer的具体实现:

    // ATimer.hpp
    #ifndef _ATIMER_H
    #define _ATIMER_H
    
    #include <vector>
    #include <thread>
    #include <atomic>
    #include <functional>
    #include <boost/timer.hpp>
    #include <boost/asio.hpp>
    
    template<typename Duration = boost::posix_time::milliseconds>
    class ATimer
    {
    public:
        ATimer() : m_timer(m_ios, Duration(0)), m_isSingleShot(false) {}
        ~ATimer()
        {
            stop();
        }
    
        void start(unsigned int duration)
        {
            if (m_ios.stopped())
            {
                return;
            }
    
            m_isActive = true;
            m_duration = duration;
            m_timer.expires_at(m_timer.expires_at() + Duration(m_duration));
            m_func = [this]
            {
                m_timer.async_wait([this](const boost::system::error_code&)
                {
                    for (auto& func : m_funcVec)
                    {
                        func();
                    }
    
                    if (!m_isSingleShot)
                    {
                        m_timer.expires_at(m_timer.expires_at() + Duration(m_duration));
                        m_func();
                    }
                });
            };
    
            m_func();
            m_thread = std::thread([this]{ m_ios.run(); });
        }
    
        void stop()
        {
            m_ios.stop();
            if (m_thread.joinable())
            {
                m_thread.join();
            }
            m_isActive = false;
        }
    
        void bind(const std::function<void()>& func)
        {
            m_funcVec.emplace_back(func);
        }
    
        void setSingleShot(bool isSingleShot)
        {
            m_isSingleShot = isSingleShot; 
        }
    
        bool isSingleShot() const
        {
            return m_isSingleShot;
        }
    
        bool isActive() const
        {
            return m_isActive;
        }
    
    private:
        boost::asio::io_service m_ios;
        boost::asio::deadline_timer m_timer;
        std::function<void()> m_func = nullptr;
        std::vector<std::function<void()>> m_funcVec;
        std::thread m_thread;
        unsigned int m_duration = 0;
        std::atomic<bool> m_isSingleShot;
        bool m_isActive = false;
    };
    
    #endif
    
    
    

    下面是ATimer的具体使用例子:

    // main.cpp
    #include <iostream>
    #include "ATimer.hpp"
    
    void test()
    {
        std::cout << "Timer thread id: " << std::this_thread::get_id() << std::endl;
    }
    
    int main()
    {
        std::cout << "Main thread id: " << std::this_thread::get_id() << std::endl;
    
        ATimer<boost::posix_time::minutes> t0;
        t0.setSingleShot(true);// 单次调用
        t0.bind(test);
        t0.start(1);// 一分钟之后调用
    
        ATimer<> t;//默认使用毫秒定时器
        t.bind(test);
        t.bind([]{ std::cout << "Hello C++" << std::endl; });
        t.start(1000);//每1000ms调用一次
    
        std::cin.get();
        t0.stop();
        t.stop();
        std::cout << "Tiemr stop" << std::endl;
    
        std::cin.get();
        std::cout << "Process end" << std::endl;
    
        return 0;
    }
    
    
    

    该例子的github地址:https://github.com/chxuan/samples/tree/master/ATimer

  • 相关阅读:
    python基础学习Day15 面向对象、类名称空间、对象名称空间 (2)
    python基础学习Day14 内置函数 匿名函数
    python基础学习Day12 生成器、列表推导式、字典的表达式、字典键值对的互换、集合推导式
    python基础学习Day11 函数名的应用、闭包、迭代器
    python基础学习Day10 函数形参的动态参数、*args **kwargs 命名空间 global 与 nonlocal
    python基础学习Day9 函数的初识,实参、形参、
    定时器定时循环执行和只执行一次
    CocoaPods 安装和使用
    tableView的cell之间间隔显示空白区域
    去掉tableView空白区域的分割线
  • 原文地址:https://www.cnblogs.com/highway-9/p/5737421.html
Copyright © 2020-2023  润新知