项目描述
轻量级、高精度定时器系统,用于解决多线程环境下任务的延时执行与周期性调度问题。该系统采用时间轮(Timing Wheel)算法优化时间复杂度,利用双向链表管理任务队列,支持毫秒级精度的任务插入、删除、启动与停止。系统通过互斥锁(Mutex)保证线程安全,有效避免了多线程竞争导致的数据不一致问题,适用于需要精准控制任务执行时机的嵌入式或后台服务场景。
核心功能
任务管理 :实现了任务的动态插入(InsertTimer)、按名称删除(DeleteTask)、链表清空及状态打印功能。
精准调度 :支持毫秒级精度的定时任务,通过系统常量 TIMER_MS(20ms)控制刷新频率,平衡了精度与性能。
并发控制 : 提供了定时器的启动(StartTimer)与停止(StopTimer)接口,能够处理大量并发任务的调度需求。
状态监控: 提供了链表打印(PrintTimer)功能,实时监控当前待执行任务列表及剩余时间。
技术亮点
算法优化 (时间轮思想): 采用差值法存储时间(每个节点存储与前一节点的时间差),将时间复杂度从 O(n) 降低至 O(1) 或 O(log n) 级别(取决于插入逻辑),显著提升了大量任务下的插入与刷新效率。
线程安全设计 : 在所有关键操作(插入、删除、刷新)中使用 std::lock_guard 进行加锁,确保了在多线程环境下的数据一致性与安全性。
资源管理 : 利用 std::list 的动态内存特性,避免了固定数组的内存浪费;通过 std::this_thread::sleep_for 实现非阻塞式等待,保证了主线程的响应性。
异常处理: 设计了完善的错误码机制(ErrNo),对同名任务插入、空指针调用等异常情况进行捕获与处理,增强了系统的健壮性。
项目文件图

#
# 简介:定时器测试程序编译脚本
# 平台:linux
# 可执行测试程序:timer
# 测试log:timer.log
#
#!/bin/bash
g++ test.cpp timer.cpp -o timer
echo "==============$(date)============" >> timer.log
./timer >> timer.log
test.cpp
/*
* 定时器测试程序
*/
#include <iostream>
#include "timer.h"
void func(void *param)
{
std::cout << (char *)param << std::endl;
return;
}
int main()
{
/* 插入定时任务 */
Timer t;
t.InsertTimer(100, (void*)func, (void*)"t1", "t1");
t.InsertTimer(300, (void*)func, (void*)"t2", "t2");
t.InsertTimer(400, (void*)func, (void*)"t3", "t3");
t.InsertTimer(5000, (void*)func, (void*)"t4", "t4");
t.InsertTimer(10000, (void*)func, (void*)"t5", "t5");
t.InsertTimer(300, (void*)func, (void*)"t6", "t6");
t.InsertTimer(100, (void*)func, (void*)"t7", "t7");
t.InsertTimer(80, (void*)func, (void*)"t8", "t8");
t.InsertTimer(800, (void*)func, (void*)"t9", "t9");
t.InsertTimer(10000, (void*)func, (void*)"t10", "t10");
/* 打印定时器链上的定时任务 */
t.PrintTimer();
/* 启动定时器 */
std::cout << "start timer..." << std::endl;
t.StartTimer();
return 0;
}
timer.log
==============Fri Mar 13 19:37:21 CST 2026============
TimerList:
t8:80
t1:100
t7:100
t2:300
t6:300
t3:400
t9:800
t4:5000
t5:10000
t10:10000
start timer...
t8
t1
t7
t2
t6
t3
t9
t4
t5
t10
timer.h
/*
* 变更历史:
* 2026-03-13 cxb 创建该文件.
*/
/*
* @file Timer.h
* @brief
* 功能:定时器用于定时执行任务.
*/
#ifndef __TIMER_H__
#define __TIMER_H__
#include <iostream>
#include <list>
#include <mutex>
#include <thread>
#include <string>
#define TIMER_MS 20 /* 定时器链表刷新时间间隔(ms) */
/* 错误号 */
typedef enum
{
OK = 0,
ERROR
} ErrNo;
class Timer
{
private:
/* 不支持拷贝与赋值构造 */
Timer(const Timer &timer);
Timer operator=(const Timer &timer);
/* 定时器链成员 */
struct TimerMember
{
long ms; /* 定时时间 */
std::string name; /* 名字 */
void *func; /* 执行函数 */
void *param; /* 执行函数参数 */
TimerMember(unsigned long ms, void *func, void *param, std::string name):
ms(ms),
func(func),
param(param),
name(name)
{};
};
std::list<struct TimerMember> TimerList; /* 定时器链 */
std::list<struct TimerMember> ExecList; /* 待执行链 */
std::mutex TimerLock; /* 定时器链锁 */
ErrNo DeleteTimer(); /* 删除定时器链上的就绪定时器 */
ErrNo InsertExec(); /* 插入就绪定时器到待执行链 */
ErrNo ExecTimer(); /* 触发就绪定时器 */
ErrNo FlushTimer(); /* 刷新定时器链上的定时器时间 */
ErrNo ClearList(std::list<struct TimerMember> &List); /* 清空链表 */
bool ListIsEmpty(std::list<struct TimerMember> &List);/* 链表判空 */
public:
ErrNo InsertTimer(long ms, void *func, void *param, std::string name); /* 插入定时器到定时器链 */
ErrNo StartTimer(); /* 启动所有定时器 */
ErrNo StopTimer(); /* 停止所有定时器 */
ErrNo DeleteTask(std::string name); /* 删除指定定时器 */
ErrNo PrintTimer(); /* 打印定时器链上的所有定时器 */
Timer()
{
TimerList.emplace_back(0 ,nullptr, nullptr, "");
ExecList.emplace_back(0 ,nullptr, nullptr, "");
TimerList.clear();
ExecList.clear();
};
~Timer()
{
TimerList.clear();
ExecList.clear();
};
};
#endif
timer.cpp
/*
* 变更历史:
* 2024-03-13 cxb 创建文件
*/
/*
* @file Timer.c
* @brief
* 功能:实现定时器功能接口
*/
#include "timer.h"
/* 定时任务 */
typedef void (*TimerFunc)(void *);
/* 判断链表是否为空 */
bool Timer::ListIsEmpty(std::list<struct TimerMember> &List)
{
if(List.size() == 0)
return true;
return false;
}
/* 插入定时任务到定时器链 */
ErrNo Timer::InsertTimer(long ms, void *func, void *param, std::string name)
{
ErrNo status = OK;
std::lock_guard<std::mutex> lock(TimerLock);
/* 校验是否包含同名任务 */
for(auto it = TimerList.begin(); it != TimerList.end(); it++)
{
if(it->name.compare(name) == 0)
{
std::cout << name << " has excited" << std::endl;
status = ERROR;
return status;
}
}
/* 定时器链为空是插入定时任务 */
if(ListIsEmpty(TimerList))
{
TimerList.emplace(TimerList.end(), ms, func, param, name);
return status;
}
/* 定时器链非空且插入到链中间 */
long AddMs = 0, TmpMs = 0;
for(auto it = TimerList.begin(); it != TimerList.end(); it++)
{
TmpMs = AddMs;
AddMs += it->ms;
if(AddMs > ms)
{
it->ms -= (ms - TmpMs);
TimerList.emplace(it, ms - TmpMs, func, param, name);
return status;
}
}
/* 定时任务插入链尾 */
TimerList.emplace(TimerList.end(), ms - AddMs, func, param, name);
return status;
}
/* 清除定时器链表中的就绪任务 */
ErrNo Timer::DeleteTimer()
{
ErrNo status = OK;
if(ListIsEmpty(TimerList))
return status;
auto it = TimerList.begin();
while(it != TimerList.end())
{
if(it->ms == 0)
{
TimerList.erase(it);
}
else
{
break;
}
it = TimerList.begin();
}
return status;
}
/* 将定时器中的就绪任务插入到待执行链 */
ErrNo Timer::InsertExec()
{
ErrNo status = OK;
if(ListIsEmpty(TimerList) || (TimerList.front().ms != 0))
{
return status;
}
for(auto it = TimerList.begin(); it != TimerList.end(); it++)
{
/* 从链表头开始第一个等待时间不为0之前的任务均为就绪任务 */
if(it->ms == 0)
{
ExecList.insert(ExecList.end(), *it);
}
else
{
break;
}
}
return status;
}
/* 清空链表 */
ErrNo Timer::ClearList(std::list<struct TimerMember> &List)
{
ErrNo status = OK;
List.clear();
return status;
}
/* 运行待执行链上的就绪任务 */
ErrNo Timer::ExecTimer()
{
ErrNo status = OK;
int tmp = 0;
/* 运行就绪任务 */
for(auto it = ExecList.begin(); it != ExecList.end(); it++)
{
if(it->func != nullptr)
{
TimerFunc f = (TimerFunc)it->func;
f(it->param);
}
}
/* 清空就绪链*/
status = ClearList(ExecList);
return status;
}
/* 刷新定时器链表上的定时任务的定时时间 */
ErrNo Timer::FlushTimer()
{
ErrNo status = OK;
long TmpMs = TIMER_MS;
for(auto it = TimerList.begin(); it != TimerList.end(); it++)
{
if(TmpMs == 0)
break;
if(it->ms < TmpMs)
{
/* 超时打印并更新定时时间*/
if(it->ms != 0)
{
it->ms = 0;
TmpMs -= it->ms;
std::cout << it->name << "超时" << TmpMs - it->ms << "ms" << std::endl;
}
}
else
{
/* 更新为超时时间*/
it->ms -= TmpMs;
TmpMs = 0;
}
}
return status;
}
/* 启动定时器 */
ErrNo Timer::StartTimer()
{
ErrNo status = OK;
for(;;)
{
std::lock_guard<std::mutex> lock(TimerLock);
if(ListIsEmpty(TimerList))
break;
/* 每隔TIMER_MS刷新并执行定时任务 */
std::this_thread::sleep_for(std::chrono::microseconds(TIMER_MS));
/* 刷新定时*/
FlushTimer();
/* 运行并清除定时任务 */
InsertExec();
ExecTimer();
DeleteTimer();
}
return status;
}
/* 停止定时器 */
ErrNo Timer::StopTimer()
{
ErrNo status = OK;
std::lock_guard<std::mutex> lock(TimerLock);
/* 清空定时器链和待执行链 */
status = ClearList(ExecList);
status = ClearList(TimerList);
return status;
}
/* 删除定时任务 */
ErrNo Timer::DeleteTask(std::string name)
{
ErrNo status = OK;
std::lock_guard<std::mutex> lock(TimerLock);
/* 删除待执行链上的任务 */
for(auto it = ExecList.begin(); it != ExecList.end(); it++)
{
if(it->name.compare(name))
{
ExecList.erase(it);
}
}
/* 删除定时器器链上的任务 */
for(auto it = TimerList.begin(); it != TimerList.end(); it++)
{
if(it->name.compare(name))
{
TimerList.erase(it);
}
}
return status;
}
/* 打印定时器链上的定时任务 */
ErrNo Timer::PrintTimer()
{
ErrNo status = OK;
long TimerMs = 0;
std::lock_guard<std::mutex> lock(TimerLock);
std::cout << "TimerList:" << std::endl;
for(auto it = TimerList.begin(); it != TimerList.end(); it++)
{
TimerMs += it->ms;
std::cout << it->name << ":" << TimerMs << std::endl;
}
return status;
}