网狐定时器引擎分析
先贴出来网狐源码:
#ifndef WH_THREAD_HEAD_FILE
#define WH_THREAD_HEAD_FILE#pragma once#include "ServiceCoreHead.h"////线程对象
class SERVICE_CORE_CLASS CWHThread
{//状态变量
private:volatile bool m_bRun; //运行标志//线程变量
private:UINT m_uThreadID; //线程标识HANDLE m_hThreadHandle; //线程句柄//函数定义
protected://构造函数CWHThread();//析构函数virtual ~CWHThread();//接口函数
public://获取状态virtual bool IsRuning();//启动线程virtual bool StartThread();//终止线程virtual bool ConcludeThread(DWORD dwMillSeconds);//功能函数
public://线程标识UINT GetThreadID() { return m_uThreadID; }//线程句柄HANDLE GetThreadHandle() { return m_hThreadHandle; }//投递消息LRESULT PostThreadMessage(UINT uMessage, WPARAM wParam, LPARAM lParam);//事件函数
protected://运行事件virtual bool OnEventThreadRun() { return true; }//开始事件virtual bool OnEventThreadStrat() { return true; }//终止事件virtual bool OnEventThreadConclude() { return true; }//内部函数
private://线程函数static unsigned __stdcall ThreadFunction(LPVOID pThreadData);
};//#endif
#include "StdAfx.h"
#include "WHThread.h"//
//结构定义//启动参数
struct tagThreadParameter
{bool bSuccess; //是否错误HANDLE hEventFinish; //事件句柄CWHThread * pServiceThread; //线程指针
};////构造函数
CWHThread::CWHThread()
{//设置变量m_bRun=false;m_uThreadID=0;m_hThreadHandle=NULL;return;
}//析构函数
CWHThread::~CWHThread()
{//停止线程ConcludeThread(INFINITE);return;
}//状态判断
bool CWHThread::IsRuning()
{//运行检测if (m_hThreadHandle==NULL) return false;if (WaitForSingleObject(m_hThreadHandle,0)!=WAIT_TIMEOUT) return false;return true;
}//启动线程
bool CWHThread::StartThread()
{//效验状态ASSERT(IsRuning()==false);if (IsRuning()==true) return false;//清理变量if (m_hThreadHandle!=NULL) {//关闭句柄CloseHandle(m_hThreadHandle);//设置变量m_uThreadID=0;m_hThreadHandle=NULL;}//变量定义tagThreadParameter ThreadParameter;ZeroMemory(&ThreadParameter,sizeof(ThreadParameter));//设置变量ThreadParameter.bSuccess=false;ThreadParameter.pServiceThread=this;ThreadParameter.hEventFinish=CreateEvent(NULL,FALSE,FALSE,NULL);//效验状态ASSERT(ThreadParameter.hEventFinish!=NULL);if (ThreadParameter.hEventFinish==NULL) return false;//启动线程m_bRun=true;m_hThreadHandle=(HANDLE)::_beginthreadex(NULL,0,ThreadFunction,&ThreadParameter,0,&m_uThreadID);//错误判断if (m_hThreadHandle==INVALID_HANDLE_VALUE){CloseHandle(ThreadParameter.hEventFinish);return false;}//等待事件WaitForSingleObject(ThreadParameter.hEventFinish,INFINITE);CloseHandle(ThreadParameter.hEventFinish);//判断错误if (ThreadParameter.bSuccess==false){ConcludeThread(INFINITE);return false;}return true;
}//停止线程
bool CWHThread::ConcludeThread(DWORD dwMillSeconds)
{//停止线程if (IsRuning()==true){//设置变量m_bRun=false;//停止等待if (WaitForSingleObject(m_hThreadHandle,dwMillSeconds)==WAIT_TIMEOUT){return false;}}//设置变量if (m_hThreadHandle!=NULL){//关闭句柄CloseHandle(m_hThreadHandle);//设置变量m_uThreadID=0;m_hThreadHandle=NULL;}return true;
}//投递消息
LRESULT CWHThread::PostThreadMessage(UINT uMessage, WPARAM wParam, LPARAM lParam)
{//状态效验ASSERT((m_uThreadID!=0)&&(m_hThreadHandle!=NULL));if ((m_uThreadID==0)||(m_hThreadHandle==NULL)) return false;//投递消息if (::PostThreadMessage(m_uThreadID,uMessage,wParam,lParam)==FALSE){DWORD dwLastError=GetLastError();return dwLastError;}return 0L;
}//线程函数
unsigned __stdcall CWHThread::ThreadFunction(LPVOID pThreadData)
{//随机种子srand((DWORD)time(NULL));//变量定义tagThreadParameter * pThreadParameter=(tagThreadParameter *)pThreadData;CWHThread * pServiceThread=pThreadParameter->pServiceThread;//启动通知try{pThreadParameter->bSuccess=pServiceThread->OnEventThreadStrat(); } catch (...){//设置变量ASSERT(FALSE);pThreadParameter->bSuccess=false;}//设置事件bool bSuccess=pThreadParameter->bSuccess;ASSERT(pThreadParameter->hEventFinish!=NULL);if (pThreadParameter->hEventFinish!=NULL) SetEvent(pThreadParameter->hEventFinish);//线程处理if (bSuccess==true){//线程运行while (pServiceThread->m_bRun){
#ifndef _DEBUG//运行版本try{if (pServiceThread->OnEventThreadRun()==false){break;}}catch (...) { }
#else//调试版本if (pServiceThread->OnEventThreadRun()==false){break;}
#endif}//停止通知try{ pServiceThread->OnEventThreadConclude();} catch (...) { ASSERT(FALSE); }}//中止线程_endthreadex(0L);return 0L;
}//
#ifndef TIMERENGINE_HEAD_FILE
#define TIMERENGINE_HEAD_FILE#pragma once//系统头文件#include "KernelEngineHead.h"
#include "QueueServiceEvent.h"#define TIMER_SPACE 25 //时间间隔//类说明
class CTimerEngine;////定时器线程
class CTimerThread : public CWHThread
{//变量定义
protected:CTimerEngine * m_pTimerEngine; //定时器引擎//函数定义
public://构造函数CTimerThread(void);//析构函数virtual ~CTimerThread(void);//功能函数
public://配置函数bool InitThread(CTimerEngine * pTimerEngine);//重载函数
private://运行函数virtual bool OnEventThreadRun();
};////定时器子项
struct tagTimerItem
{DWORD wTimerID; //定时器 IDDWORD dwElapse; //定时时间DWORD dwTimeLeave; //倒计时间DWORD dwRepeatTimes; //重复次数WPARAM wBindParam; //绑定参数
};//定时器子项数组定义
typedef CWHArray CTimerItemPtr;////定时器引擎
class CTimerEngine : public ITimerEngine
{friend class CTimerThread;//状态变量
protected:bool m_bService; //运行标志CTimerItemPtr m_TimerItemFree; //空闲数组CTimerItemPtr m_TimerItemActive; //活动数组//组件变量
protected:CCriticalSection m_CriticalSection; //线程锁CTimerThread m_TimerThread; //定时器线程IQueueServiceSink * m_pIQueueServiceSink; //通知回调//函数定义
public://构造函数CTimerEngine(void);//析构函数virtual ~CTimerEngine(void);//基础接口
public://释放对象virtual VOID Release() { if (IsValid()) delete this; }//是否有效virtual bool IsValid() { return AfxIsValidAddress(this, sizeof(CTimerEngine)) ? true : false; }//接口查询virtual void * QueryInterface(const IID & Guid, DWORD dwQueryVer);//接口函数
public://设置定时器virtual bool SetTimer(DWORD dwTimerID, DWORD dwElapse, DWORD dwRepeat, WPARAM dwBindParameter);//删除定时器virtual bool KillTimer(DWORD dwTimerID);//删除定时器virtual bool KillAllTimer();//设置接口virtual bool SetTimerEngineEvent(IUnknownEx * pIUnknownEx);//管理接口
public://开始服务virtual bool StartService();//停止服务virtual bool ConcludeService();//内部函数
private://定时器通知void OnTimerThreadSink();
};//#endif
#include "StdAfx.h"
#include "TimerEngine.h"
#include "TraceService.h" ////宏定义
#define NO_TIME_LEFT DWORD(-1) //不响应时间////构造函数
CTimerThread::CTimerThread(void)
{m_pTimerEngine = NULL;
}//析构函数
CTimerThread::~CTimerThread(void)
{
}//配置函数
bool CTimerThread::InitThread(CTimerEngine * pTimerEngine)
{if (pTimerEngine == NULL) return false;//设置变量m_pTimerEngine = pTimerEngine;return true;
}//运行函数
bool CTimerThread::OnEventThreadRun()
{ASSERT(m_pTimerEngine != NULL);Sleep(TIMER_SPACE);m_pTimerEngine->OnTimerThreadSink();return true;
}////构造函数
CTimerEngine::CTimerEngine(void)
{m_bService = false;m_pIQueueServiceSink = NULL;
}//析构函数
CTimerEngine::~CTimerEngine(void)
{INT_PTR i = 0;//停止服务ConcludeService();//清理内存tagTimerItem * pTimerItem = NULL;for (i = 0; i < m_TimerItemFree.GetCount(); i++){pTimerItem = m_TimerItemFree[i];ASSERT(pTimerItem != NULL);SafeDelete(pTimerItem);}for (i = 0; i < m_TimerItemActive.GetCount(); i++){pTimerItem = m_TimerItemActive[i];ASSERT(pTimerItem != NULL);SafeDelete(pTimerItem);}m_TimerItemFree.RemoveAll();m_TimerItemActive.RemoveAll();return;
}//接口查询
void * CTimerEngine::QueryInterface(const IID & Guid, DWORD dwQueryVer)
{QUERYINTERFACE(ITimerEngine, Guid, dwQueryVer);QUERYINTERFACE_IUNKNOWNEX(ITimerEngine, Guid, dwQueryVer);return NULL;
}//设置定时器
bool CTimerEngine::SetTimer(DWORD dwTimerID, DWORD dwElapse, DWORD dwRepeat, WPARAM dwBindParameter)
{DEBUG_GUARD;//锁定资源CWHDataLocker lock(m_CriticalSection);////效验参数ASSERT(dwRepeat > 0L);if (dwRepeat == 0) return false;//查找定时器bool bTimerExist = false;tagTimerItem * pTimerItem = NULL;for (INT_PTR i = 0; i < m_TimerItemActive.GetCount(); i++){pTimerItem = m_TimerItemActive[i];ASSERT(pTimerItem != NULL);if (pTimerItem->wTimerID == dwTimerID){bTimerExist = true;break;}}//创建定时器if (bTimerExist == false){INT_PTR nFreeCount = m_TimerItemFree.GetCount();if (nFreeCount > 0){pTimerItem = m_TimerItemFree[nFreeCount-1];ASSERT(pTimerItem != NULL);m_TimerItemFree.RemoveAt(nFreeCount - 1);}else{try{pTimerItem = new tagTimerItem;ASSERT(pTimerItem != NULL);if (pTimerItem == NULL) return false;}catch (...){return false;}}}//设置参数ASSERT(pTimerItem != NULL);pTimerItem->wTimerID = dwTimerID;pTimerItem->wBindParam = dwBindParameter;pTimerItem->dwElapse = dwElapse;pTimerItem->dwRepeatTimes = dwRepeat;//提前20个粒度进行通知 - TIMER_SPACE * 20if (pTimerItem->dwRepeatTimes == 1)pTimerItem->dwTimeLeave = __max(TIMER_SPACE, pTimerItem->dwElapse - TIMER_SPACE * 20);elsepTimerItem->dwTimeLeave = pTimerItem->dwElapse;//激活定时器if (bTimerExist == false)m_TimerItemActive.Add(pTimerItem);return true;
}//删除定时器
bool CTimerEngine::KillTimer(DWORD dwTimerID)
{DEBUG_GUARD;//锁定资源CWHDataLocker lock(m_CriticalSection);////查找定时器tagTimerItem * pTimerItem = NULL;for (INT_PTR i = 0; i < m_TimerItemActive.GetCount(); i++){pTimerItem = m_TimerItemActive[i];ASSERT(pTimerItem != NULL);if (pTimerItem->wTimerID == dwTimerID){m_TimerItemActive.RemoveAt(i);m_TimerItemFree.Add(pTimerItem);return true;;}}return false;
}//删除定时器
bool CTimerEngine::KillAllTimer()
{//锁定资源CWHDataLocker lock(m_CriticalSection);////删除定时器m_TimerItemFree.Append(m_TimerItemActive);m_TimerItemActive.RemoveAll();return true;
}//开始服务
bool CTimerEngine::StartService()
{//效验状态if (m_bService == true){CTraceService::TraceString(TEXT("定时器引擎重复启动,启动操作忽略"), TraceLevel_Warning);return true;}//设置变量if (m_TimerThread.InitThread(this) == false){CTraceService::TraceString(TEXT("定时器引擎线程服务初始化失败"), TraceLevel_Exception);return false;}//启动服务if (m_TimerThread.StartThread() == false){CTraceService::TraceString(TEXT("定时器引擎线程服务启动失败"), TraceLevel_Exception);return false;}SetThreadPriority(m_TimerThread.GetThreadHandle(), REALTIME_PRIORITY_CLASS);//设置变量m_bService = true;return true;
}//停止服务
bool CTimerEngine::ConcludeService()
{//设置变量m_bService = false;//停止线程m_TimerThread.ConcludeThread(INFINITE);//设置变量m_TimerItemFree.Append(m_TimerItemActive);m_TimerItemActive.RemoveAll();return true;
}//设置接口
bool CTimerEngine::SetTimerEngineEvent(IUnknownEx * pIUnknownEx)
{//效验参数ASSERT(pIUnknownEx != NULL);ASSERT(m_bService == false);if (m_bService == true) return false;if (pIUnknownEx == NULL) return false;//设置接口ASSERT(pIUnknownEx != NULL);m_pIQueueServiceSink = QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx, IQueueServiceSink);ASSERT(m_pIQueueServiceSink != NULL);return (m_pIQueueServiceSink != NULL);
}//定时器通知
void CTimerEngine::OnTimerThreadSink()
{DEBUG_GUARD;//缓冲锁定CWHDataLocker lock(m_CriticalSection);////查询定时器tagTimerItem * pTimerItem = NULL;for (INT_PTR i = m_TimerItemActive.GetCount() - 1; i >= 0; i--){//效验参数pTimerItem = m_TimerItemActive[i];ASSERT(pTimerItem != NULL);if (pTimerItem == NULL) return;ASSERT(pTimerItem->dwTimeLeave > 0);//定时器处理bool bKillTimer = false;pTimerItem->dwTimeLeave -= TIMER_SPACE;if (pTimerItem->dwTimeLeave <= 0L){//设置次数if (pTimerItem->dwRepeatTimes != TIMES_INFINITY){ASSERT(pTimerItem->dwRepeatTimes > 0);pTimerItem->dwRepeatTimes--;if (pTimerItem->dwRepeatTimes == 0L){bKillTimer = true;m_TimerItemActive.RemoveAt(i);m_TimerItemFree.Add(pTimerItem);}}//设置时间if (bKillTimer == false)//提前20个粒度进行通知 - TIMER_SPACE * 20{if (pTimerItem->dwRepeatTimes == 1)pTimerItem->dwTimeLeave = __max(TIMER_SPACE, pTimerItem->dwElapse - TIMER_SPACE * 20);elsepTimerItem->dwTimeLeave = pTimerItem->dwElapse;}try{//BYTE cbBuffer[MAX_ASYNCHRONISM_DATA] = {0}; //接收缓冲//匿名BYTE cbBuffer[sizeof(NTY_TimerEvent)] = {0}; //接收缓冲//投递消息NTY_TimerEvent * pTimerEvent = (NTY_TimerEvent *)cbBuffer;pTimerEvent->dwTimerID = pTimerItem->wTimerID;pTimerEvent->dwBindParameter = pTimerItem->wBindParam;m_pIQueueServiceSink->OnQueueServiceSink(EVENT_TIMER, cbBuffer, sizeof(NTY_TimerEvent));}catch (...) { }}}
}////建立对象函数
extern "C" __declspec(dllexport) void * CreateTimerEngine(const GUID & Guid, DWORD dwInterfaceVer)
{//建立对象CTimerEngine * pTimerEngine = NULL;try{pTimerEngine = new CTimerEngine();if (pTimerEngine == NULL) throw TEXT("创建失败");void * pObject = pTimerEngine->QueryInterface(Guid, dwInterfaceVer);if (pObject == NULL) throw TEXT("接口查询失败");return pObject;}catch (...) {}//清理对象SafeDelete(pTimerEngine);return NULL;
}//
解读CWHThread类:
说是CWHThread类感觉它更像一个接口,要想使用此类必须重新写一个类继承它。重写OnEventThreadRun()函数,(OnEventThreadStrat和OnEventThreadConclude是可选重载),不明白IsRuning()和StartThread()和ConcludeThread三个函数为什么设为虚函数,感觉这三个函数没有重写的必要。线程函数设为私有的,这是因为类对象不可能调用该函数,此函数只共本类其他函数内部调用。由于线程函数要吗是全局函数,要吗是静态成员函数,本类就是一个线程,所以本类的线程函数是静态成员函数。这个静态成员函数有本类的StartThread成员函数调用。那么ThreadFunction去掉什么函数呢?让他掉用成员函数OnEventThreadRun,只要我们子类重新OnEventThreadRun函数就可以达到做任何业务的目的。那么问题就出来了,OnEventThreadRun函数是个静态成员函数,他如何调用本类的非静态成员函数呢,本代码提供了一种很好的机制,ThreadFunction函数加个参数,参数之一是指向CWHThread实例的类指针,通过这个指针再去调用成员函数,长见识了。
解读CWHThread类:
类互相缠绕的问题:
CWHThread的子类CTimerThread,专为CTimerEngine定制的子类,为什么这样说呢,因为类CTimerThread除了在CTimerEngine类里面有个实例外,此类不再会有其他实例。我们大眼一看,CTimerThread类里面包含了CTimerEngine类实例指针的属性,CTimerEngine里面包含了CTimerThread类的实例属性。这种开发方式采用了impl技术。(类CTimerEngine为了访问类CTimerThread的私有函数OnEventThreadRun把类CTimerThread添加为自己的友元类,再次不再赘述)。下面分析一下类互相缠绕的原因,类CTimerThread必须有个属性是CTimerEngine类的指针或者对象,因为只有这样它才会知道线程要干什么活(干活方式是用自己的成员函数OnEventThreadRun调用类CTimerEngine的成员函数)。接着是类CTimerEngine为什么会包含类CTimerThread的实例,用通俗的话来说就是类CTimerEngine会告诉类CTimerThread给谁在干活,以及什么时候开始干,具体到代码就是CTimerEngine类成员函数StartService调用m_TimerThread.InitThread(this)告诉类CTimerThread在给谁干活,m_TimerThread.StartThread()告诉类CTimerThread什么时候开始干。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
