该定时器引擎基于线程驱动 + 时间片轮询 + 队列事件分发 的核心思路实现,整体架构分为定时器管理 、定时线程驱动 、事件分发三个核心模块,以下是详细的实现流程和原理:
一、核心设计思路
- 时间片轮询:通过独立线程以固定时间间隔(默认 25ms)触发时间检查,避免高频系统调用,降低资源消耗;
- 定时器对象池:维护 "空闲 / 活跃" 定时器链表,复用定时器对象减少内存分配开销;
- 事件队列分发:定时器到期后不直接执行逻辑,而是将事件投递到队列服务,由业务层异步处理,解耦定时器核心与业务逻辑。
二、核心组件与依赖
| 组件 | 作用 |
|---|---|
| CTimerThread | 定时器驱动线程,以固定时间片睡眠后触发时间检查 |
| CTimerEngine | 定时器核心管理器,负责定时器的增删、时间计算、到期事件投递 |
| CQueueServiceEvent | 事件投递器,将到期的定时器事件投递到队列服务(IQueueService) |
| CQueueService | 队列服务,接收定时器事件并异步分发给业务层的回调接口 |
三、完整实现流程
1. 初始化阶段(BeginService)





cpp
// TimerEngine.cpp -> CTimerEngine::OnTimerThreadSink
void CTimerEngine::OnTimerThreadSink() {
CThreadLockHandle LockHandle(&m_ThreadLock);
// 1. 无活跃定时器则直接返回
if (m_dwTimeLeave==NO_TIME_LEFT) return;
// 2. 累计已过时间,更新剩余时间
m_dwTimeLeave -= m_dwTimerSpace;
m_dwTimePass += m_dwTimerSpace;
// 3. 检查是否有定时器到期(m_dwTimeLeave==0表示到检查点)
if (m_dwTimeLeave==0) {
DWORD dwTimeLeave=NO_TIME_LEFT;
for (INT_PTR i=0;i<m_TimerItemActive.GetCount();) {
tagTimerItem* pTimerItem = m_TimerItemActive[i];
// 计算当前定时器剩余时间
pTimerItem->dwTimeLeave -= m_dwTimePass;
// 4. 定时器到期
if (pTimerItem->dwTimeLeave==0L) {
// 投递定时器事件到队列服务
m_AttemperEvent.PostTimerEvent(pTimerItem->wTimerID, pTimerItem->wBindParam);
// 5. 处理重复次数
if (pTimerItem->dwRepeatTimes != TIMER_REPEAT_TIMER) {
if (pTimerItem->dwRepeatTimes==1) {
// 单次定时器:移到空闲池
m_TimerItemActive.RemoveAt(i);
m_TimerItemFree.Add(pTimerItem);
bKillTimer=true;
} else {
// 多次定时器:减少次数,重置剩余时间
pTimerItem->dwRepeatTimes--;
pTimerItem->dwTimeLeave = pTimerItem->dwElapse;
}
} else {
// 无限重复:重置剩余时间
pTimerItem->dwTimeLeave = pTimerItem->dwElapse;
}
}
// 6. 更新全局最近到期时间
if (!bKillTimer) {
i++;
dwTimeLeave=__min(dwTimeLeave, pTimerItem->dwTimeLeave);
}
}
// 7. 重置时间累计,准备下一轮
m_dwTimePass=0L;
m_dwTimeLeave=dwTimeLeave;
}
}



CTimerEngine::SetTimer → 初始化定时器 → CTimerThread(25ms轮询)→ OnTimerThreadSink(检查到期) → CQueueServiceEvent::PostTimerEvent → CQueueService::AddToQueue → 队列线程异步触发业务回调
总结:该定时器引擎是典型的 "时间片轮询 + 对象池 + 事件队列" 实现,兼顾了性能、线程安全和业务解耦,适合服务端高并发场景下的定时任务管理。