(有什么问题欢迎指教,企鹅:2172243813 更多资讯尽在www.ttkmwl.com)
CTimerEngine成员变量:
//状态变量
DWORD
m_dwTimerSpace;
//时间间隔,这个值后来应该是给了定时器线程
protected:
bool
m_bService;
//运行标志
DWORD
m_dwTimePass;
//经过时间
DWORD
m_dwTimeLeave;
//倒计时间
CTimerItemPtr
m_TimerItemFree;
//空闲数组
CTimerItemPtr
m_TimerItemActive;
//活动数组
这些是分析定时器线程函数需要了解的成员变量,其次是线程同步:
从代码中可以看出所有对:m_TimerItemActive;
m_TimerItemFree;的操作都是在一个线程锁的保护之下的。
//定时器通知
voidCTimerEngine::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
{
//效验参数
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;
}
定时器线程:
通过CTimerThread绕一圈以后最终被循环执行的实际上是这个函数(m_dwTimerSpace控制最小时间):
CTimerEngine:
启动一个定时器线程,循环遍历定时器,如果发现满足出发条件的定时器就投递一个定时器消息到CQueueServiceEvent对象。