最近有个大牛给我教了时间轮算法,并且看了他实现的源码,认为自己已经理解了他所实现的思想,这里将我的代码和理解分享一下:
时间轮是模仿钟表的方式,秒针走一圈,分针走一格,只有最里圈的任务需要执行,转一圈后分针(外一层)指向下一格,将那一格的节点重新插入,那么就会插入到秒针(最里圈)。
以下方式还有一些不足,我会再做修改:
#ifndef __TIMEWHEEL_H__
#define __TIMEWHEEL_H__
#include "templock.h"//锁的实现文件
#include <time.h>
#include <map>
#include <list>
#define SLOT_LEVEL 4 //时间圈的层数
#define TIME_NEAR 8
#define TIME_LEVEL 6
#define TIME_NEAR_SLOT (1 << TIME_NEAR) //最里圈执行圈的槽数 1 0000 0000
#define TIME_LEVEL_SLOT (1 << TIME_LEVEL) //除最里圈外的每圈的桶数 0100 0000
#define TIME_NEAR_MASK ((1 << TIME_NEAR) - 1) //判断任务是否移动到最里圈的掩码 1111 1111
#define TIME_LEVEL_MASK ((1 << TIME_LEVEL) - 1) //判断任务放在哪一圈的掩码 0011 1111
// 精度
#define PRECISION 10
typedef void(*TimeOutCb)(void*);
typedef void(*CancelCb)(void*);
typedef struct TimerNode
{
unsigned int expireTime;//过期时间
TimeOutCb timeOutCb; // 时间节点的回调处理函数
CancelCb cancelCb; // 取消删除时间节点
void* arg; // 回调函数的参数
int timeNodeId;//定时任务节点的ID,用来删除节点
bool isNear; // 是否处在最近
int rowNO; // 行,所处圈数
int colNO;// 列,所在位置
};
class TimeWheel
{
public:
TimeWheel(void);
public:
~TimeWheel(void);
private:
std::list<TimerNode*> nearTimerSlot[TIME_NEAR_SLOT]; //最里面的时间轮槽数,总共256个
std::list<TimerNode*> levelTimerSlot[SLOT_LEVEL][TIME_LEVEL_SLOT]; // 后面总共4层,每层都是64个槽
unsigned int tick; // 当前的tick
unsigned int startTime; // 开始时间
unsigned int currentTime; //当前时间
private:
TempLock timeLock;
int timeNodeId; // 时间点的ID号
std::map<int, TimerNode*> timeNodeMap; //定时任务节点ID和地址的映射
volatile bool stopFlag; //是否停止
publi