查看: 264|回复: 1

网狐棋牌(四) TimerEngine

[复制链接]

8

主题

37

帖子

224

积分

vip会员

Rank: 1

积分
224
发表于 2020-3-27 16:14:50 | 显示全部楼层 |阅读模式
CTimerEngine成员变量:
    //状态变量
    DWORD                                m_dwTimerSpace;                    //时间间隔,这个值后来应该是给了定时器线程
protected:
    bool                                m_bService;                        //运行标志
    DWORD                                m_dwTimePass;                    //经过时间
    DWORD                                m_dwTimeLeave;                    //倒计时间
    CTimerItemPtr                        m_TimerItemFree;                //空闲数组
    CTimerItemPtr                        m_TimerItemActive;                //活动数组
这些是分析定时器线程函数需要了解的成员变量,其次是线程同步:
从代码中可以看出所有对:m_TimerItemActive;  m_TimerItemFree;的操作都是在一个线程锁的保护之下的。


定时器线程:
通过CTimerThread绕一圈以后最终被循环执行的实际上是这个函数(m_dwTimerSpace控制最小时间):



  • //定时器通知  
  • void CTimerEngine::OnTimerThreadSink()  
  • {  
  •     //锁定资源  
  •     CThreadLockHandle LockHandle(&m_ThreadLock);  
  •   
  •     //倒计时间  
  •     if (m_dwTimeLeave==NO_TIME_LEFT)   
  •     {  
  •         ASSERT(m_TimerItemActive.GetCount()==0);  
  •         return;  
  •     }  
  •   
  •     //减少时间  
  •     ASSERT(m_dwTimeLeave>=m_dwTimerSpace);  
  •     m_dwTimeLeave-=m_dwTimerSpace;  
  •     m_dwTimePass+=m_dwTimerSpace;  
  •   
  •     //查询定时器  
  •     if (m_dwTimeLeave==0)  
  •     {  
  •         bool bKillTimer=false;  
  •         tagTimerItem * pTimerItem=NULL;  
  •         DWORD dwTimeLeave=NO_TIME_LEFT;  
  •         for (INT_PTR i=0;i<m_TimerItemActive.GetCount();)  
  •         {  
  •             //效验参数  
  •             pTimerItem=m_TimerItemActive;  
  •             ASSERT(pTimerItem!=NULL);  
  •             ASSERT(pTimerItem->dwTimeLeave>=m_dwTimePass);  
  •   
  •             //定时器处理  
  •             bKillTimer=false;  
  •             // 这一行做了--操作  
  •             pTimerItem->dwTimeLeave -= m_dwTimePass;  
  •             if (pTimerItem->dwTimeLeave==0L)  
  •             {  
  •                 //发送通知  
  •                 m_AttemperEvent.PostTimerEvent(pTimerItem->wTimerID,pTimerItem->wBindParam);  
  •   
  •                 //设置次数  
  •                 if (pTimerItem->dwRepeatTimes!=TIMER_REPEAT_TIMER)  
  •                 {  
  •                     ASSERT(pTimerItem->dwRepeatTimes>0);  
  •                     if (pTimerItem->dwRepeatTimes==1L)  
  •                     {  
  •                         bKillTimer=true;  
  •                         m_TimerItemActive.RemoveAt(i);  
  •                         m_TimerItemFree.Add(pTimerItem);  
  •                     }  
  •                     else pTimerItem->dwRepeatTimes--;  
  •                 }  
  •   
  •                 //设置时间,从新开始倒计时  
  •                 if (bKillTimer==false) pTimerItem->dwTimeLeave=pTimerItem->dwElapse;  
  •             }  
  •   
  •             //增加索引  
  •             if (bKillTimer==false)   
  •             {  
  •                 i++;  
  •                 dwTimeLeave=__min(dwTimeLeave,pTimerItem->dwTimeLeave);  
  •                 ASSERT(dwTimeLeave%m_dwTimerSpace==0);  
  •             }  
  •         }  
  •   
  •         //设置响应  
  •         m_dwTimePass=0L;  
  •         m_dwTimeLeave=dwTimeLeave;  
  •     }  
  •   
  •     return;  
  • }  

CTimerEngine:
启动一个定时器线程,循环遍历定时器,如果发现满足出发条件的定时器就投递一个定时器消息到CQueueServiceEvent对象。
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | enginedx注册

本版积分规则

 
 



邮件留言:


 
返回顶部