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

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

一、核心设计思路
  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 → 队列线程异步触发业务回调

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

相关推荐
Dawson Zhu7 小时前
《Agentic Design Patterns》第 9 章导读:学习与适应(Learning and Adaptation)
人工智能·语言模型·架构·aigc·agi
姜鱼问生8 小时前
Linux 日志增量统计:inode + offset 方案(不丢不重)
架构
软件工程师_罗小东8 小时前
我把这套 AI 落地方案,讲成一条任务闭环
架构
阡陌数智8 小时前
Llama 4 MoE 架构深度拆解:交替稀疏专家设计与生产环境推理落地实战
架构·llama
波加曼大王10 小时前
# vLLM不要迷信PagedAttention神话,聊聊线上藏着的内部碎片陷阱
java·架构
xn713310 小时前
EmbeddingGemma 2 270M 实测:278 Chunk、32 个查询与 RRF 反例
人工智能·后端·架构
漠野92310 小时前
画布的保存按钮背后,站着一个编译器
架构
两万五千个小时10 小时前
DeepSeek Harness 从 0 开始:20 goal模式
人工智能·程序员·架构
漠野92310 小时前
让每个节点自己决定:要不要跑,还是循环跑
架构
dcacheor10 小时前
现代桌面播放器的交互困境与架构演进:从单窗流媒体走向多模态视讯工作台
架构