zoukankan      html  css  js  c++  java
  • 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);

    }

  • 相关阅读:
    asp.net core 中TagHelper使用
    vs2015 添加命令提示工具
    关于MVC中Start.cs文件的作用
    Sql Server的两个小技巧
    用vue.js重构订单计算页面
    用vue.js实现购物车功能
    一步步实现自己的ORM(五)
    一步步实现自己的ORM(四)
    将Object转换成Dictionary方法
    一步步实现自己的ORM(三)
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/3894236.html
Copyright © 2011-2022 走看看