/* Time event structure */
/* 时间事件结构体 */
typedef struct aeTimeEvent {
//时间事件id,累加增加,id降序链表
long long id; /* time event identifier. */
//时间秒数
long when_sec; /* seconds */
//时间毫秒
long when_ms; /* milliseconds */
//时间事件中的处理函数
aeTimeProc *timeProc;
//被删除的时候将会调用的方法
aeEventFinalizerProc *finalizerProc;
//客户端数据
void *clientData;
//时间结构体内的下一个结构体
struct aeTimeEvent *next;
} aeTimeEvent; b, 定时事件和周期性事件
执行一次和重复执行的区别,定时需要在处理完后删除事件。周期需要更新when时间。根据事件处理器的返回值区分是那个时间事件。
c, 使用无序链表实现,每次需要遍历所有链表,效率低。但现在redis正常只有一个serverCron...benchmark下有两个。实现没含量,最小堆实现都比这个好,事件多了会死循环,切效率低,这里不多讲了。
3,事件的循环调度
a, 结构体
typedef struct aeFiredEvent {
//文件描述符 fd
int fd;
// 触发的事件 读写
int mask;
} aeFiredEvent;// 已触发的事件
// 事件循环结构体
/* State of an event based program */
typedef struct aeEventLoop {
int maxfd; /* highest file descriptor currently registered */
int setsize; /* max number of file descriptors tracked */
// 记录最大的定时事件 id + 1
long long timeEventNextId;
// 用于系统时间的矫正
time_t lastTime; /* Used to detect system clock skew */
// I/O 文件事件表
aeFileEvent *events; /* Registered events */
// 被触发的事件表
aeFiredEvent *fired; /* Fired events */
// 定时事件表
aeTimeEvent *timeEventHead;
// 事件循环结束标识
int stop;
// 对于不同的 I/O 多路复用技术,有不同的数据,详见各自实现
void *apidata; /* This is used for polling API specific data */
// 新的循环前需要执行的操作
aeBeforeSleepProc *beforesleep;
} aeEventLoop;
结构体之间的关系如下图