C/C++定时器的使用


前言

有时候执行一个任务的时候,需要一直不断的采集数据,如果把采集数据的任务放在主任务,将会造成主任务的阻塞,通常的做法是将采集数据的任务创建一个子线程来完成。但是还有另一种方法,是通过定时器来定时采集数据。这样可以避免线程使用的复杂性,也更加容易调试。下面就列举了一个C/C++定时器的例程!

话不多说,直接放例程!

1.cMyTimer.h

代码如下:

#pragma once
#include "string"
#include "list"
using namespace std;

struct stTimer
{
	unsigned timeElapce;	//定时器间隔运行时间
	unsigned timeCreate;	//定时器创建时间
	unsigned timeLastRun;	//定时器上次执行时间
	unsigned id;					//定时器ID号
	int iParam;				//预留参数
	string	strParam;		//预留参数
	bool bDel;				//是否已被删除

	stTimer()
	{
		timeCreate = 0;
		timeLastRun = 0;
		id = -1;
		iParam = 0;
		bDel = false;
	}
};

typedef list<stTimer> stTimerList;
typedef list<stTimer>::iterator itTimerList;

class cMyTimer
{
public:
	cMyTimer();
	virtual ~cMyTimer();

	//添加定时器
	void AddTimer(unsigned timerId, unsigned timeMs,int param = 0,
		char* p=NULL);
	//删除定时器
	void DeleteTimer(int id);

	//定时器处理
	virtual int OnTimer(int id,int iParam,string str) = 0;
	
	//检测定时器运行
	bool TimerRun();
	
	//清除所有定时器
	void ClearTimer();
	//定时检测删除定时器
	void CheckDelTimer();	
private:

	stTimerList m_timerList;	//定时器列表
};

2.cMyTimer.cpp

代码如下:

#include "stdafx.h"
#include "cMyTimer.h"
#include "windows.h"
#include "process.h"

cMyTimer::cMyTimer()
{
}

cMyTimer::~cMyTimer()
{
	ClearTimer();
}

void cMyTimer::ClearTimer()
{
	for (itTimerList it = m_timerList.begin();it != m_timerList.end();++it)
	{		
		it->bDel = true;
	}
}

void CheckTimerRun(void* p)
{
	cMyTimer* pTimer = (cMyTimer*)p;
	if (pTimer == NULL)
	{
		return;
	}
	while(1)
	{
		pTimer->CheckDelTimer();
		
		//检测是否有定时器要运行
		if(!pTimer->TimerRun())
		{
			_endthread();
		}
		Sleep(20);
	}
}

//添加定时器
void cMyTimer::AddTimer(unsigned timerId,unsigned timeMs,int param,char* p)
{
	if (timeMs == 0)
	{
		return;
	}
	stTimer stTimerTemp;
	stTimerTemp.bDel = false;
	stTimerTemp.id = timerId;
	stTimerTemp.iParam = param;
	if (p != NULL)
	{
		stTimerTemp.strParam = p;
	}
	
	unsigned timeNow = GetTickCount();
	stTimerTemp.timeCreate = timeNow;
	stTimerTemp.timeLastRun = timeNow;
	stTimerTemp.timeElapce = timeMs;
	m_timerList.push_back(stTimerTemp);
	if (m_timerList.size() == 1)
	{
		//说明此时是第一个定时器
		_beginthread(CheckTimerRun,0,this);
	}
}

//删除定时器
void cMyTimer::DeleteTimer(int id)
{
	for (itTimerList it = m_timerList.begin();it != m_timerList.end();++it)
	{
		if (it->id == id)
		{
			it->bDel = true;
			return;
		}
	}
}

//定时器处理
//int cMyTimer::OnTimer(int id,int iParam,string str)
//{
//	return 1;
//}

//定时检测删除定时器
void cMyTimer::CheckDelTimer()
{
	for (itTimerList it = m_timerList.begin();it != m_timerList.end();)
	{
		if (it->bDel)
		{
			m_timerList.erase(it);
			it = m_timerList.begin();
			continue;
		}
		++it;
	}
}

bool cMyTimer::TimerRun()
{
	if (m_timerList.size() == 0)
	{
		return false;
	}
	unsigned timeNow = GetTickCount();
	for (itTimerList it = m_timerList.begin();it != m_timerList.end();++it)
	{
		if (timeNow-it->timeLastRun >= it->timeElapce)
		{
			it->timeLastRun = timeNow;
			if(OnTimer(it->id,it->iParam,it->strParam) == 0)
			{
				//删除定时器
				it->bDel = true;
			}
			continue;
		}
	}
	return true;
}

3.Test.h

代码如下:

#pragma once
#include "cMyTimer.h"
using namespace std;

class Derived : public cMyTimer				//派生类
{
public:										//公有的
	Derived();								//构造函数
	~Derived();								//析构函数:清除所有定时器

	//定时器回调函数
	virtual int OnTimer(int id, int iParam, string str);
};

4.Test.c

代码如下:

#include "Test.h"
#include "windows.h"
#include "process.h"
#include <conio.h>							//_kbhit()

Derived::Derived()							//派生类构造函数
{
}

Derived::~Derived()							//派生类析构函数
{
}

//纯虚函数在派生类一定要实现
int Derived::OnTimer(int id, int iParam, string str)//定时器处理
{
	static long num;						//静态变量
	printf("num=%d\r\n", num++);
	return 1;
}

int main(int argc, char* argv[])
{
	Derived Test;							//派生类实例化
	Test.AddTimer(0, 1000);					//增加一个定时器0,定时时间为1000ms
	Test.OnTimer(0,0,"");					//调用定时器0处理函数。
	while (!_kbhit())
	{
	}
	Test.DeleteTimer(0);					//删除定时0
	return 0;
}

想要实现定时器功能,首先得创建一个定时器.设定好定时器的定时器事件:
通过函数void AddTimer(unsigned timerId, unsigned timeMs, int param = 0, char* p = NULL); 创建好一个指定 定时时间和定时器ID 的定时器.
然后再通过派生类函数 int OnTimer(int id,int iParam,string str); 实现需要定时执行的任务!

工程框图

如图所示:
C/C++定时器的使用

执行结果

如图所示:
C/C++定时器的使用
结果:1000ms打印一次!!!

上一篇:彩色工业相机 RGB8转 RGBPlanar格式方法


下一篇:bitmap的实现