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); 实现需要定时执行的任务!

工程框图

如图所示:
在这里插入图片描述

执行结果

如图所示:
结果:1000ms打印一次
结果:1000ms打印一次!!!

C++中,可以使用计时器(timer)来实现定时器的功能。常用的实现方式有以下几种: 1. 使用C++11中的<chrono>头文件 该头文件中提供了高精度计时的类和函数,可以用于实现定时器功能。例如,以下代码实现了一个一秒钟的定时器: ``` #include <iostream> #include <chrono> #include <thread> int main() { auto start = std::chrono::steady_clock::now(); while (true) { auto end = std::chrono::steady_clock::now(); auto diff = end - start; if (std::chrono::duration_cast<std::chrono::seconds>(diff).count() >= 1) { std::cout << "One second passed." << std::endl; start = end; } } return 0; } ``` 2. 使用Windows API中的SetTimer函数 SetTimer函数是Windows API中的一个函数,可以用于创建一个定时器。例如,以下代码实现了一个每隔一秒钟输出一次的定时器: ``` #include <iostream> #include <Windows.h> void CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { std::cout << "One second passed." << std::endl; } int main() { SetTimer(NULL, 0, 1000, TimerProc); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } ``` 3. 使用第三方库 除了上述两种方式,还可以使用第三方库来实现定时器功能。例如,Boost库中提供了定时器的实现,可以方便地使用。以下是一个使用Boost库的定时器的示例: ``` #include <iostream> #include <boost/asio.hpp> void TimerHandler(const boost::system::error_code& ec) { if (!ec) { std::cout << "One second passed." << std::endl; } } int main() { boost::asio::io_context io; boost::asio::steady_timer timer(io, boost::asio::chrono::seconds(1)); timer.async_wait(TimerHandler); io.run(); return 0; } ``` 以上是几种常用的C++定时器实现方式,您可以根据自己的实际需求进行选择。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值