您的位置:首页 > 编程语言 > C语言/C++

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

2014-01-04 12:27 337 查看
此文参考了网上的一篇《C++中利用多线程实现定时器》链接在这里:/article/1704872.html

这个有一个问题, 就是不能同时有多个定时器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得到毫秒级的。

还有如,用线程实现定时器好像一般都不这么做, 请大家多多指出问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: