开发者社区> double2li> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

简介: 概述 最近在工作上需要用到定时器,然后看到boost里面的deadline_timer可以实现一个定时器,所以就直接将其封装成了ATimer类,方便使用,ATimer有以下优点: 可以支持纳秒、毫秒、秒、分、小时定时。
+关注继续查看

概述

最近在工作上需要用到定时器,然后看到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;
}

from:http://www.cnblogs.com/highway-9/p/5737421.html

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【Java多线程】定时器Timer
在任务的执行时间未到之前,可能判断次数很多,比较耗费CPU,而且没有必要一值判断,只需在一定时间内进行判断执行时间到没到即可,所以在还没有到执行时间时,使用wait(时间)来让该线程进行等待,在创建任务时唤醒等待即可,因为新的任务可能需要在刚才等待执行任务之前执行,也就是新创建的任务执行时间已经到了,所以要使用notify唤醒执行任务的线程继续进行判断时间是否执行,而且这个原因也是使用wait不使用sleep的原因,如果使用sleep,在新创建任务的执行时间在sleep等待结束时间之前,等待的线程没有办法唤醒,也就不能执行时间到了的任务
0 0
ASIO的定时器
ASIO的定时器
0 0
多线程十 Timer
多线程十 Timer
0 0
【Android 异步操作】Timer 定时器 ( Timer 与 TimerTask 基本使用 | Timer 定时器常用用法 | Timer 源码分析 )
【Android 异步操作】Timer 定时器 ( Timer 与 TimerTask 基本使用 | Timer 定时器常用用法 | Timer 源码分析 )
0 0
java多线程--定时器Timer的使用
  定时的功能我们在手机上见得比较多,比如定时清理垃圾,闹钟,等等.定时功能在java中主要使用的就是Timer对象,他在内部使用的就是多线程的技术.    Time类主要负责完成定时计划任务的功能,就是在指定的时间的开始执行某个任务.
644 0
Timer 定时器
1.概述 定时执行特定的任务。 2.类与方法 2.1Timer java.util.Timer 一个Timer对应一个线程。一个Timer可以调度多个任务。若一个任务有异常,可能这个Timer线程就不能正常工作 了,其他的任务也受牵连。一般用它调度轻量级的任务。 java.util.Timer#schedule(java.util.TimerTask task, java.ut
717 0
C# Timer 定时器应用
        关于C#中timer类 在C#里关于定时器类就有3个:         1.定义在System.Windows.Forms里         2.定义在System.Threading.Timer类里         3.定义在System.Timers.Timer类里         System.Windows.Forms.Timer是应用于WinForm中的,
1910 0
定时器 Timer
定时器 Timer 不多说,上代码。
504 0
+关注
double2li
一个在IT行业摸爬滚打的老司机
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载