自定義的定時器

該定時器實現了線程之間的互鎖。使用時先初始化全局對象vector,設定好使用的定時器的個數,

#pragma once
#include "afxmt.h"
#include <vector>
using namespace std;


//定時器
typedef struct tagSPLCTimer
{
	LONGLONG TimerStart;
	LONGLONG TimerEnd;
	double Time;

}SPLCTimer;


vector<SPLCTimer>    g_PLC_Timer ;//全局變量,定時器集合
//定時器操作類
class CustomTimer
{
public:
	CustomTimer();
	~CustomTimer();

private:
	//線程互斥用-定時器線程鎖
	CCriticalSection m_PLCCritical_Timer_Mutix;


public:
	//初始化定時器
	void InitTimer(unsigned long TimerID, unsigned long bTime);

	//獲取時鐘基準
	LONGLONG GetClock();

	//死循環時間
	void SleepTime(double Time);//ms

	//定時器是否結束
	bool IsTimerEnd(unsigned long TimerID);

	//獲取已經定時的時間
	void GetUsedTime(unsigned long TimerID, unsigned long& bTime);

	//清除定時器已經記的時間
	void RstTimer(unsigned long TimerID);

public:

};

#include "pch.h"
#include "CustomTimer.h"

CustomTimer::CustomTimer()
{
}

CustomTimer::~CustomTimer()
{
}

void CustomTimer::InitTimer(unsigned long TimerID, unsigned long bTime)
{
	double			dfMinus, dfTim;
	LARGE_INTEGER	litmp;
	LONGLONG		dfFreq;
	QueryPerformanceFrequency(&litmp);
	dfFreq = litmp.QuadPart;

	unsigned long nTimerSize = g_PLC_Timer.size();
	if (TimerID < 0 || TimerID >= nTimerSize)
	{
		CString info;
		info.Format(_T("索引定時器ID號(%d)的範圍不對"), TimerID);
		AfxMessageBox(info, MB_TOPMOST);
		return;
	}
	if (!IsTimerEnd(TimerID))
	{
		CString info;
		info.Format(_T("索引定時器ID號(%d)+IsTimerEnd沒完成卻去InitTimer初始化"), TimerID);
		AfxMessageBox(info, MB_TOPMOST);
	}
	m_PLCCritical_Timer_Mutix.Lock();//線程鎖
	g_PLC_Timer[TimerID].TimerStart = GetClock();
	g_PLC_Timer[TimerID].Time = bTime;
	m_PLCCritical_Timer_Mutix.Unlock();//線程鎖

}

LONGLONG CustomTimer::GetClock()
{
	LONGLONG time = 0;
	LARGE_INTEGER  litmp;
	LONGLONG       QPart1;
	QueryPerformanceCounter(&litmp);
	QPart1 = litmp.QuadPart;
	time = (LONGLONG)(QPart1);
	return time;
}

void CustomTimer::SleepTime(double Time)
{
	LARGE_INTEGER  litmp;
	LONGLONG       QPart1, QPart2;;
	double         dfMinus = 0, dfFreq = 0, dfTim = 0;
	double dfTgTime = 0;

	QueryPerformanceFrequency(&litmp);//獲得機器內部定時器的時鐘頻率
	dfFreq = (double)litmp.QuadPart;
	QueryPerformanceCounter(&litmp);
	QPart1 = litmp.QuadPart;// 獲得初始值
	dfTgTime = Time * 0.001;//轉化爲分鐘
	while (dfTim < dfTgTime)
	{
		QueryPerformanceCounter(&litmp);
		QPart2 = litmp.QuadPart;//獲得中止值
		dfMinus = (double)(QPart2 - QPart1);
		dfTim = dfMinus / dfFreq;
	}
}

bool CustomTimer::IsTimerEnd(unsigned long TimerID)
{
	double			dfMinus, dfTim;
	LARGE_INTEGER	litmp;
	LONGLONG		dfFreq;
	QueryPerformanceFrequency(&litmp);
	dfFreq = litmp.QuadPart;

	unsigned long nTimerSize = g_PLC_Timer.size();
	if (TimerID < 0 || TimerID >= nTimerSize)
	{
		CString info;
		info.Format(_T("索引定時器ID號(%d)的範圍不對"), TimerID);
		AfxMessageBox(info, MB_TOPMOST);
		return false;
	}

	m_PLCCritical_Timer_Mutix.Lock();//線程鎖
	g_PLC_Timer[TimerID].TimerEnd = GetClock();
	dfMinus = g_PLC_Timer[TimerID].TimerEnd - g_PLC_Timer[TimerID].TimerStart;
	if (dfMinus < 0)
		dfMinus = 0;
	dfTim = (int)10000 * dfMinus / dfFreq;
	dfTim /= 10.0;

	bool Retn = false;
	if (dfTim >= g_PLC_Timer[TimerID].Time) //必須是下一個週期到來
	{
		g_PLC_Timer[TimerID].TimerStart = 0;
		g_PLC_Timer[TimerID].TimerEnd = 0;
		g_PLC_Timer[TimerID].Time = 0;
		Retn = true;
	}
	else
	{
		Retn = false;
	}

	m_PLCCritical_Timer_Mutix.Unlock(); //線程鎖
	return Retn;

}

void CustomTimer::GetUsedTime(unsigned long TimerID, unsigned long & bTime)
{

	LARGE_INTEGER  litmp;
	LONGLONG         dfMinus, dfFreq, dfTim, tempdfTim;
	QueryPerformanceFrequency(&litmp);
	dfFreq = litmp.QuadPart;

	unsigned long nTimerSize = g_PLC_Timer.size();
	if (TimerID < 0 || TimerID >= nTimerSize)
	{
		CString info;
		info.Format(_T("索引定時器ID號(%d)的範圍不對"), TimerID);
		AfxMessageBox(info, MB_TOPMOST);
		return;
	}

	m_PLCCritical_Timer_Mutix.Lock();//線程鎖

	g_PLC_Timer[TimerID].TimerEnd = GetClock();
	dfMinus = g_PLC_Timer[TimerID].TimerEnd - g_PLC_Timer[TimerID].TimerStart;
	if (dfMinus < 0)//內存溢出
		dfMinus += 0xffffffffffffffff;
	tempdfTim = 1000 * dfMinus;
	if (tempdfTim < 0)//內存溢出
		tempdfTim += 0xffffffffffffffff;
	dfTim = tempdfTim / dfFreq;

	bool Retn = false;
	if (dfTim >= g_PLC_Timer[TimerID].Time)
	{
		g_PLC_Timer[TimerID].TimerStart = 0;
		g_PLC_Timer[TimerID].TimerEnd = 0;
		g_PLC_Timer[TimerID].Time = 0;
		bTime = 0;//輸出
	}
	else
	{
		bTime = (unsigned long)dfTim; //輸出
	}


	m_PLCCritical_Timer_Mutix.Unlock(); //線程鎖
}

void CustomTimer::RstTimer(unsigned long TimerID)
{
	unsigned long nTimerSize = g_PLC_Timer.size();
	if (TimerID < 0 || TimerID >= nTimerSize)
	{
		CString info;
		info.Format(_T("索引定時器ID號(%d)的範圍不對"), TimerID);
		AfxMessageBox(info, MB_TOPMOST);

		return;
	}

	m_PLCCritical_Timer_Mutix.Lock(); //線程鎖
	g_PLC_Timer[TimerID].TimerStart = 0;
	g_PLC_Timer[TimerID].TimerEnd = 0;
	g_PLC_Timer[TimerID].Time = 0;
	m_PLCCritical_Timer_Mutix.Unlock(); //線程鎖
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章