线程实现定时器(windows下C++版)

来源:互联网 发布:vb中sqr是什么意思 编辑:程序博客网 时间:2024/06/01 07:50

此文参考了网上的一篇《C++中利用多线程实现定时器》链接在这里:http://blog.csdn.net/rabbit729/article/details/2729065

这个有一个问题, 就是不能同时有多个定时器ID, 而且一旦启动一个,就启动一个线程, 会把之前的成员变量给覆盖掉,这里实现如下, 话不多说, 直接上代码, 欢迎各位拍砖及提出问题, 都会虚心解决。

//MyTimer.h

#pragma once#include <Windows.h>#include <map>typedef void (*TimerCallBack)(int); struct Timer_Info{unsigned int nElapse;time_t beginTime;TimerCallBack onTimer;};typedef std::map<int, Timer_Info> TIMER_LIST;class MyTimer{public:MyTimer();~MyTimer();void startTimer(int timeID, unsigned int nElapse, TimerCallBack func);void endTimer(int timeID);static DWORD WINAPI ThreadFunc(LPVOID lpParam);private:TIMER_LIST m_timerList;//定时器列表,存放多个相关定时器信息HANDLE m_hThread;};


//MyTimer.cpp

#include "stdafx.h"#include "MyTimer.h"#include <iostream>#include <time.h>using namespace std;MyTimer::MyTimer(){m_hThread = CreateThread(NULL, 0, ThreadFunc, LPVOID(this), 0, NULL);}MyTimer::~MyTimer(){CloseHandle(m_hThread);m_hThread = NULL;}void MyTimer::startTimer(int timeID, unsigned int nElapse, TimerCallBack func){Timer_Info info = {nElapse, time(NULL), func};m_timerList.insert(std::make_pair(timeID, info));//此处没有判断timeID是否存在就直接insert,是因为map::insert当key存在时,insert会失败。}void MyTimer::endTimer(int timeID){m_timerList.erase(timeID);//直接erase原理同insert,不存在时, erase失败}DWORD WINAPI MyTimer::ThreadFunc(LPVOID lpParam){MyTimer *pThis = (MyTimer*)(lpParam);if (pThis == NULL)return -1;while (true){if (pThis->m_timerList.size() != 0)//只在定时器列表中有ID时才作处理{time_t endTime = time(NULL);int diff;//在定时器列表中,轮流查询哪个定时器时间到达。for (TIMER_LIST::iterator iter =pThis->m_timerList.begin(); iter != pThis->m_timerList.end(); iter++){diff = (int)difftime(endTime, iter->second.beginTime);if (diff >= iter->second.nElapse ){iter->second.onTimer(iter->first);iter->second.beginTime = endTime;}}}}}

//测试代码main.cpp

// MyTestSolution.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <iostream>#include "MyTimer.h"using namespace std;void OnTimer(int timeID){if (timeID == 1){cout<<"timer:"<<1<<endl;}if (timeID == 2){cout<<"timer:"<<2<<endl;}}int main() {MyTimer timer;timer.startTimer(1, 2, OnTimer);timer.startTimer(2, 2, OnTimer);Sleep(10000);}

执行结果如下:

timer:1

timer:2

timer:1

timer:2

timer:1

timer:2

timer:1

timer:2

timer:1

timer:2

请按任意键继续. . .


代码可供优化和改良的还有很多, 比如精度可用QueryPerformanceFrequency(), QueryPerformanceCounter()等API得到毫秒级的。

还有如,用线程实现定时器好像一般都不这么做, 请大家多多指出问题。


0 0
原创粉丝点击