网狐的定时器引擎架构理解

该定时器引擎基于线程驱动 + 时间片轮询 + 队列事件分发 的核心思路实现,整体架构分为定时器管理定时线程驱动事件分发三个核心模块,以下是详细的实现流程和原理:

一、核心设计思路
  1. 时间片轮询:通过独立线程以固定时间间隔(默认 25ms)触发时间检查,避免高频系统调用,降低资源消耗;
  2. 定时器对象池:维护 "空闲 / 活跃" 定时器链表,复用定时器对象减少内存分配开销;
  3. 事件队列分发:定时器到期后不直接执行逻辑,而是将事件投递到队列服务,由业务层异步处理,解耦定时器核心与业务逻辑。

二、核心组件与依赖

组件 作用
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 → 队列线程异步触发业务回调

总结:该定时器引擎是典型的 "时间片轮询 + 对象池 + 事件队列" 实现,兼顾了性能、线程安全和业务解耦,适合服务端高并发场景下的定时任务管理。

相关推荐
heimeiyingwang9 小时前
【架构实战】异步化改造:线程池与消息队列的取舍
架构
Mr.HeBoYan10 小时前
一次持续三天才出现的丢包故障——深入解析 DPDK Memory Ordering、rte_ring 与 CPU Memory Barrier (下)
linux·网络·算法·架构·dpdk
名字还没想好☜11 小时前
Go 的 time.Ticker 陷阱:定时任务里被忽略的内存泄漏与正确关闭
java·数据库·golang·go·定时器
锋行天下11 小时前
打造企业内部知识库系统RAG全栈项目
前端·后端·架构
这个DBA有点耶12 小时前
索引碎片与统计信息维护:执行计划突然变差的隐形杀手
mysql·程序员·架构
Discipline~Hai12 小时前
ARM01-ARM体系架构
linux·c语言·arm开发·架构
XUHUOJUN12 小时前
AKS 不是安装在 Windows Server 上,而是运行在 Windows Server 之上的 Azure 平台能力
windows·架构·k8s·azure local·azure stack
Cosolar13 小时前
AI Agent 架构原理详解:从一次提问到任务完成的完整闭环
人工智能·后端·架构
会周易的程序员14 小时前
Libnodave S7 通信库:架构设计与实现解析
linux·c++·物联网·架构·c·s7·工业协议
小小猪的春天14 小时前
团队级 Code Review Skill 实践:4个人、4个AI、1套规则,CR从找bug变成做决策
后端·架构