定时器Timer的实现

定时器Timer的实现

        定时器在实际项目中会用的比较平凡。因此,本文首先介绍定时器Timer的windows版本,跨平台的定时器将在下一篇文章中介绍。它们的源代码均用C++编写。源代码详见:https://github.com/duankai/Timer

1.      定时器结构体类型

typedef struct TIMER_T
{
    int uiTimerID;
    long lMilliSecond;
    void	(* lpProcessFunction)(void * pvData);
    void * pvData;
} TIMER_T;

2.      定时器类

class Timer
{
public:
    Timer();
    int SetTimer(
        long lMilliSecond, //the millisecond of timer
        void (*_lpProcessFunction)(void * pvData),
        void * pvData
        );
    bool CancleTimer(int ulTimerID);
    bool GetInstanceStatus();
    ~Timer();
private:
    static DWORD WINAPI ScanTimerQueue(LPVOID lp);
    static int CmpFunc(TIMER_T * t1, TIMER_T * t2);
private:
    static SortBinaryTree<TIMER_T> * m_pstSBT;
    static int m_uiTimerID;
    bool m_bInit;
    HANDLE m_hScan;
    std::map<int, TIMER_T *> m_map;
};

3.      定时器的设置

int Timer::SetTimer(
    long lMilliSecond, //the millisecond of timer
    void (*_lpProcessFunction)(void * pvData),
    void * pvData
)
{
    TIMER_T * stTimerInstc = (TIMER_T *)malloc(sizeof(TIMER_T));
    if (!stTimerInstc)
    {
        return INVILID_TIMER_ID;
    }
    stTimerInstc->lpProcessFunction = _lpProcessFunction;
    /*The GetTickCount() function will be zero when your system run more than 49.7 days.*/
    stTimerInstc->lMilliSecond = GetTickCount() + lMilliSecond;
    stTimerInstc->uiTimerID = ++m_uiTimerID;
    stTimerInstc->pvData = pvData;
    if (m_pstSBT->InsertTreeNode(stTimerInstc))
    {
        m_map.insert(std::pair<int,TIMER_T *>(m_uiTimerID, stTimerInstc));
        return m_uiTimerID;
    } 
    else
    {
        free(stTimerInstc);
        stTimerInstc = NULL;
        return INVILID_TIMER_ID; 
    }
}

4.      取消定时器

bool Timer::CancleTimer(int ulTimerID)
{
    std::map<int, TIMER_T *>::iterator itor_map;
    itor_map = m_map.find(ulTimerID);
    if (itor_map == m_map.end())
    {
        return false;
    }
    if (m_pstSBT->DeleteTreeNode((void *)itor_map->second))
    {
        free(itor_map->second);
        itor_map->second = NULL;
        m_map.erase(itor_map);
        return true;
    }
    else
    {
        return false; 
    }
}


5.      定时器扫描队列

DWORD WINAPI Timer::ScanTimerQueue(LPVOID lp)
{
    LONG ulCurrTime;
    while(1)
    {
        ulCurrTime = GetTickCount();
        if (NULL != m_pstSBT->GetSmallestNode() &&
            m_pstSBT->GetSmallestNode()->lMilliSecond <= ulCurrTime)
        {
            TIMER_T * pstTimer = m_pstSBT->DeleteSmallestNode();
            if (NULL != pstTimer)
            {
                 pstTimer->lpProcessFunction(pstTimer->pvData);
                 free(pstTimer);
                 pstTimer = NULL;
             }
         }
         SLEEP(100);
     }
     return 0;
}


        总结:Timer实现了定时器的主要功能,设置定时器和取消定时器,同时,在设置定时器时通过提供一个回调函数来完成相关工作。定时器存储在SortBinaryTree中,便于扫描。

        存在的问题:由于在设置定时器的时候采用了GetTickCount()函数,因此限制了服务器的连续运行时间不得超过49.7天,在大型服务代码的编写中,这将通过其他替代函数完成这一类似功能。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值