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

摘要:
概述计时器需要在最近的工作中使用,然后在boost_timer中查看截止日期。timer可以实现计时器,因此它直接封装为ATimer类以便于使用。ATimer具有以下优点:它可以支持纳秒、毫秒、秒、分钟和小时计时。计时器可以随时停止。支持单次呼叫。因为使用了截止时间计时器,所以计时准确。ATimer和Qt使用与QTimer相同的方法。如果没有类似的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;
}

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

免责声明:文章转载自《使用boost的deadline_timer实现一个异步定时器》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[C]x字符转义序列nginx代理访问vue打包dist碰到的问题下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

转:Jmeter 用户思考时间(User think time),定时器,和代理服务器(proxy server)

在负载测试中需要考虑的的一个重要要素是思考时间(think time), 也就是在两次成功的访问请求之间的暂停时间。 有多种情形挥发导致延迟的发生: 用户需要时间阅读文字内容,或者填表,或者查找正确的链接等。未认真考虑思考时间经常会导致测试结果的失真。例如,估计数值不恰当,也就是被测系统可以支持的最多用户量(并发用户)看起来好像要少一些等。Jmeter提...

【STM32F429】第7章 ThreadX操作系统移植(GCC)

论坛原始地址(持续更新):http://www.armbbs.cn/forum.php?mod=viewthread&tid=99514 第7章   ThreadX操作系统移植(GCC) 本章节将为大家介绍ThreadX内核的GCC方式移植和设计框架,理论上不建议初学者直接学习,因为本章节涉及到的知识点很多,建议对ThreadX的应用有一些了解后再...

stm32之PWM学习

下图是一个STM32普通PWM形成的图形原理说明 自动重装载寄存器(ARR)用于确定波形的频率(即周期)、捕获比较寄存器(CCRx)(用于确定占空比的) PWM的工作过程如下:首先ARR寄存器里面的值确定了一个PWM周期,就是我们上面举的那两个例子中的“1秒”(注意这个周期是在PWM系统初始化的时候写入ARR寄存器的,写入以后一般就不再改动了)。然后...

(stm32f103学习总结)—stm32定时器中断

一、定时器介绍STM32F1的定时器非常多,由2个基本定时器(TIM6、TIM7)、4个通 用定时器(TIM2-TIM5)和2个高级定时器(TIM1、TIM8)组成。基本定 时器的功能最为简单,类似于51单片机内定时器。通用定时器是在基本 定时器的基础上扩展而来,增加了输入捕获与输出比较等功能。高级定 时器又是在通用定时器基础上扩展而来,增加了可编程死区互...

STM32学习笔记——定时器中断(向原子哥学习)

定时器中断 STM32的定时器功能十分强大,有TIME1和TIME8等高级定时器,也有TIME2~TIME5等通用定时器,还有TIME6和TIME7等基本定时器。在本章中,我们将利用TIM3的定时器中断来控制DS1的翻转,在主函数用DS0的翻转来提示程序正在运行。选择难度适中的通用定时器来介绍。 1、STM32通用定时器简介 STM32的通用定时器是一个通...

Java 定时器

Java 定时器 1. 概述 Timer 可以按计划执行重复的任务或者定时执行指定任务,这是因为 Timer 内部利用了一个后台线程 TimerThread 有计划地执行指定任务。 Timer:是一个实用工具类,该类用来调度一个线程(schedule a thread) ,使它可以在将来某一时刻执行。Java 的 Timer 类可以调度一个任务运行一次...