標籤:
先貼出來網狐源碼:
#ifndef WH_THREAD_HEAD_FILE#define WH_THREAD_HEAD_FILE#pragma once#include "ServiceCoreHead.h"////////////////////////////////////////////////////////////////////////////////////線程對象class SERVICE_CORE_CLASS CWHThread{//狀態變數private:volatile boolm_bRun;//運行標誌//線程變數private:UINTm_uThreadID;//線程標識HANDLEm_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{boolbSuccess;//是否錯誤HANDLEhEventFinish;//事件控制代碼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_SPACE25//時間間隔//類說明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{DWORDwTimerID;//定時器 IDDWORDdwElapse;//定時時間DWORDdwTimeLeave;//倒計時間DWORDdwRepeatTimes;//重複次數WPARAMwBindParam;//綁定參數};//定時器子項數組定義typedef CWHArray<tagTimerItem *> CTimerItemPtr;////////////////////////////////////////////////////////////////////////////定時器引擎class CTimerEngine : public ITimerEngine{friend class CTimerThread;//狀態變數protected:boolm_bService;//運行標誌CTimerItemPtrm_TimerItemFree;//空閑數組CTimerItemPtrm_TimerItemActive;//活動數組//組件變數protected:CCriticalSectionm_CriticalSection;//線程鎖CTimerThreadm_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_LEFTDWORD(-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什麼時候開始幹。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
網狐定時器引擎分析