首页 > 代码库 > c++ timer基于win消息队列

c++ timer基于win消息队列

能够承载10w个timer通信执行,说关闭就关闭,里面用了一个比較巧妙的线程处理,呵呵10W个timer就10多个线程,请大牛不要笑话,供新手学习之用

 

 

#pragma once

#include <Windows.h>

 

typedef void (CALLBACK* UXTIMERCALLBACK)(DWORD,void*);

 

#include <map>

 

#define G_UXTimerQueue (CUXTimer::GetInstance())

 

//--------------------------------------------------------------------------------------

typedef struct tegTIMERINFO 

{

HANDLE hEvent;

DWORD dwEventID;

UXTIMERCALLBACK callback;

void* pEvent;

void* pThis;

HANDLE hCmpEvent;

}TIMERINFO ;

 

typedef std::map<DWORD,TIMERINFO*> TIMERQUEUE;

 

//-------------------------------------------------------------------------------------

class CUXTimer

{

public:

CUXTimer();

virtual ~CUXTimer();

void SetTimer(DWORD dwIdEvent,DWORD dwTime,UXTIMERCALLBACK callBack,void* p);

void KillTimer(DWORD dwIdEvent);

 

static CUXTimer& GetInstance()

{

static CUXTimer u;

return u;

}

 

inline TIMERQUEUE& GetTimerQueue()

{

return m_timer_queue;

};

inline HANDLE GetTimerQueueHandle()

{

return m_hTimerQueue;

};

 

inline DWORD GetIdEvent()

{

InterlockedIncrement((LONG*)&m_longIdEvent);

if(m_longIdEvent==UINT_MAX)

m_longIdEvent = 1;

return (DWORD)m_longIdEvent;

}

protected:

private:

HANDLE m_hTimerQueue;

TIMERQUEUE m_timer_queue;

HANDLE m_hGuardThd;

 

private:

unsigned long m_longIdEvent;

  static void WINAPI TimerFunc(void*,bool);

static unsigned int __stdcall GuardThd(PVOID p);

public:

CRITICAL_SECTION m_cs_timer_queue;

static CUXTimer* m_pThis;

};

//--------------------------------------------------------------------------------------

 

 

//cpp

 

#include "stdafx.h"

#include "UXTimerQueue.h"

#include <process.h>

 

CUXTimer* CUXTimer::m_pThis = NULL;

//--------------------------------------------------------------------------------------------------------

CUXTimer::CUXTimer():m_longIdEvent(0)

{

m_hTimerQueue = CreateTimerQueue();

InitializeCriticalSection(&m_cs_timer_queue);

m_pThis = this;

m_hGuardThd = (HANDLE)_beginthreadex(NULL,0,GuardThd,0,0,0);

}

//--------------------------------------------------------------------------------------------------------

CUXTimer:: ~CUXTimer()

{

DeleteTimerQueue(m_hTimerQueue);

DeleteCriticalSection(&m_cs_timer_queue);

m_timer_queue.clear();

 

}

//--------------------------------------------------------------------------------------------------------

void CUXTimer::SetTimer(DWORD dwIdEvent,DWORD dwTime,UXTIMERCALLBACK callBack,void* p)

{

TIMERQUEUE::iterator it;

EnterCriticalSection(&m_cs_timer_queue);

TIMERINFO* t=new TIMERINFO;

t->dwEventID = dwIdEvent;

t->callback = callBack;

t->pEvent = p;

t->pThis = this;

t->hCmpEvent = CreateEvent(NULL,1,1,0);

ResetEvent(t->hCmpEvent);

if(!CreateTimerQueueTimer(&t->hEvent,m_hTimerQueue,(WAITORTIMERCALLBACK)TimerFunc,(void*)t->dwEventID,dwTime,dwTime,WT_EXECUTEINIOTHREAD))

{

if (!t->hEvent)

{

DeleteTimerQueueTimer(m_hTimerQueue,t->hEvent,t->hCmpEvent);

if (t)

{

delete t;

t = NULL;

}

LeaveCriticalSection(&m_cs_timer_queue);

return;

}

}

//预防在维护线程没有清空原有的timer,这时候这个timer反复利用,须要释放先前一个timer

if ( (it = m_timer_queue.find(dwIdEvent) ) != m_timer_queue.end())

{

if (it->second)

{

delete it->second;

it->second = NULL;

}

m_timer_queue.erase(it);

}

//将timer加入到map中用于保存

m_timer_queue.insert(std::make_pair(dwIdEvent,t));

LeaveCriticalSection(&m_cs_timer_queue);

}

//--------------------------------------------------------------------------------------------------------

void CUXTimer::KillTimer(DWORD dwIdEvent)

{

EnterCriticalSection(&m_cs_timer_queue);

TIMERQUEUE::iterator it = m_timer_queue.find(dwIdEvent);

if (it!=m_timer_queue.end())

{

it->second->pThis = NULL;

if (it->second->hEvent)

{

DeleteTimerQueueTimer(m_hTimerQueue,it->second->hEvent,it->second->hCmpEvent);

OutputDebugStringA("KILLTIMER/n");

}

 

}

LeaveCriticalSection(&m_cs_timer_queue);

 

}

//--------------------------------------------------------------------------------------------------------

void  CUXTimer::TimerFunc(void* p,bool b)

{

EnterCriticalSection(&G_UXTimerQueue.m_cs_timer_queue);

DWORD dwEventID = (DWORD)p;

TIMERQUEUE::iterator it1 = m_pThis->m_timer_queue.find(dwEventID);

if (it1 != m_pThis->m_timer_queue.end())

{

if (it1->second->pThis)

{

it1->second->callback(dwEventID,it1->second->pEvent);

}

 

}

LeaveCriticalSection(&G_UXTimerQueue.m_cs_timer_queue);

}

//--------------------------------------------------------------------------------------------------------

 

unsigned int __stdcall CUXTimer::GuardThd(PVOID p)

 {

while(1)

{

if (m_pThis->m_timer_queue.size()>0)

{

EnterCriticalSection(&G_UXTimerQueue.m_cs_timer_queue);

for (TIMERQUEUE::iterator it = m_pThis->m_timer_queue.begin();it != m_pThis->m_timer_queue.end();)

{

if(WaitForSingleObject(it->second->hCmpEvent,0) == WAIT_OBJECT_0)

{

CloseHandle(it->second->hCmpEvent);

it->second->hCmpEvent = NULL;

 

if (it->second)

{

delete it->second;

it->second = NULL;

}

 

m_pThis->m_timer_queue.erase(it++);

OutputDebugStringA("REAL_KILLTIMER/n");

}

else

it++;

}

LeaveCriticalSection(&G_UXTimerQueue.m_cs_timer_queue);

}

 

Sleep(500);

}

 

return 0;

 }

 

 //--------------------------------------------------------------------------------------------------------

 

//用法

 

int i = 0;

for (i = 0;i<10000;i++)

{

G_UXTimerQueue.SetTimer(i,500,timer,(void*)i); //启动

}

 

Sleep(10000);

 

i = 0;

for (;i<10000;i++)

{

G_UXTimerQueue.KillTimer(i); //停止

}

 

Sleep(10000);

 

for (i = 0;i<10000;i++)

{

G_UXTimerQueue.SetTimer(i,500,timer,(void*)i);

}

 

Sleep(10000);

 

i = 0;

for (;i<10000;i++)

{

G_UXTimerQueue.KillTimer(i);

}