C++实现简易定时器

该文章主要讲解的是使用C++来实现一个简易定时器功能。
首先讲解思路:
定时器最直接的就是当定时器启动后经过一定时间t后执行某个任务A。(这里可以执行完后在重置,或者直接停止。具体根据需求来实现)
我们这次选择执行一次子任务即可(不停止)
所以我们首要需要一个接口来添加定时器(AddTimerHandler),将定时的时间和所需要执行的任务添加进入;同样的,有添加定时器就必须
要有一个停止定时器(RemoveTimerHandler)这里的通过id来移除定时器。然后我们需要不停的获取时间来判断该定时器是否已经到时间了
如果到时间了就执行子任务,没有就下个刷新周期继续执行。
我们来说下计时器类如何声明和实现:
首先需要包含添加定时器(AddTimerHandler)和停止定时器(RemoveTimerHandler),然后就是更新函数(updateTimer),定时器信息结构体:
里面包含了计时器id,定时的时长,触发定时器开始的时间,执行的任务。和创建定时器id函数(CreatTimerId)以及获取时间的函数(getTime)
具体如下所示:
MyTimer.h:
#include
#include
class MyTimer {
public:
    MyTimer();
    ~MyTimer();
    typedef void(*f)();
    struct TimerInfo {
        int timerid;
        long timerout;
        long timerstart;
        bool isvalid;
        f task;
        TimerInfo(int timerid, long timerout, long timerstart, f task) {
            this->timerid = timerid;
            this->timerout = timerout;
            this->timerstart = timerstart;
            this->task = task;
            isvalid = true;
        }
    };
    int AddTimerHandler(int timeout,f task);
    void RemoveTimerHandler(const int timerid);
    void updateTimer();
    static int getTime();
    int CreatTimerId();
public:
    int Timerid;
    long Time;
    
private:
    std::list m_timerPool;
    long m_lastid;
};
注意这里的任务是通过函数指针来实现回调函数的功能(即通过函数指针来执行函数有一定的局限性,C++11标准中有更好的方法)
m_timerPool是定时器id池,通过TimerInfo中的isvalid是否有效来判断该定时器id是否有效。所以在AddTimerHandler中我们只需要将
定时器id压入m_timerPool中即可,而RemoveTimerHandler就将m_timerPool中的isvalid设置为无效。在updateTimer函数中,我们只做
两件事:1.将无效的定时器id(isvalid为false的)清除掉。2.当定时器到点时,就调用相关的任务函数。
具体的实现如下:
MyTimer.cpp:
#include"MyTimer.h"
#include
MyTimer::MyTimer() {
    m_timerPool.clear();
}
MyTimer::~MyTimer() {
    m_timerPool.clear();
}
int MyTimer::AddTimerHandler(int timeout, f task) {
    int timeid = CreatTimerId();
    m_timerPool.push_back(TimerInfo(timeid, timeout,getTime(),task));
    return timeid;
}
void MyTimer::RemoveTimerHandler(const int timerid) {
    auto it = m_timerPool.begin();
    for (; it != m_timerPool.end(); it++) {
        if (Timerid == it->timerid)
        {
            it->isvalid = false;
            break;
        }
        else {
            it++;
        }
    }
}
void MyTimer::updateTimer() {
    auto it = m_timerPool.begin();
    long currenttime = getTime();
    for (; it != m_timerPool.end();) {
        if (it->isvalid == false)
        {
            it = m_timerPool.erase(it);
            continue;
        }
        if (currenttime >= (it->timerout + it->timerstart))
        {
            it->task();//执行定时器任务
            it = m_timerPool.erase(it);
        }
        else {
            it++;
        }
    }
}
int MyTimer::getTime() {
    tm tms;
    SYSTEMTIME sys;
    GetLocalTime(&sys);

    tms.tm_year = sys.wYear - 1900;
    tms.tm_mon = sys.wMonth;
    tms.tm_mday = sys.wDay;
    tms.tm_hour = sys.wHour;
    tms.tm_min = sys.wMinute;
    tms.tm_sec = sys.wSecond;
    tms.tm_isdst = -1;//不清楚就直接-1;
    long clock = mktime(&tms);
    if (clock == -1)
    {
        std::cout << "Timer Error \n";
        return - 1;
    }
    else
        clock = clock*1000 + sys.wMilliseconds;
    return clock;
}
int MyTimer::CreatTimerId() {
    m_lastid = m_lastid % INT32_MAX;
    if (m_lastid == 0)
        m_lastid = 1;
    m_lastid++;
    return m_lastid;
}
这个地方需要注意下getTime函数,通过GetLocalTime来获取当前的时间,然后使用mktime函数来讲当前的时间点转化成秒数,最后将秒数
转换成毫秒数返回即可!tm是Windows.h中提供的,其详细的解释和使用可以自己百度了解。
最后就主函数的实现了,这里应该就很好理解。不停的循环主任务,当定时器的时间到了就执行子任务。这里的话就没有停止定时器的步骤
但是思路应该是清晰的。这里是单线程,也可以搞复杂点把多线程也加进来!
Timer.cpp:
#include
#include"MyTimer.h"
void task1() {
    //timer.RemoveTimerHandler(id);
    std::cout << "执行子任务AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n";
    system("pause");
}
void task2() {
    //timer.RemoveTimerHandler(id);
    std::cout << "执行子任务BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n";
    system("pause");
}
int main()
{
    MyTimer timer;
    long id1; 
    long id2;
    id1 = timer.AddTimerHandler(1*1000, task1);
    id2 = timer.AddTimerHandler(3 * 1000, task2);
    //std::cout << id1 << " " << id2;
    while (1) {
        std::cout << "执行主任务\n";
        timer.updateTimer();
    }
}

你可能感兴趣的:(C++自学,c++)