Redis的IO模型是Reactor模式,是利用 I/O 多路复用技术,一般多路复用的工作基本就是监听和通知。监听感兴趣的 I/O 事件(读事件,写事件),维护一个以文件描述符为主键,数据为某个预设函数的事件表,这里其实就是一个数组或者链表。当事件触发时,比如某个文件描述符可读,系统会返回文件描述符值,用这个值在事件表中找到相应的数据项(包括回调函数等),从而实现回调。同样的,定时事件也是可以实现的,因为系统提供的 I/O 多路复用技术中的函数允许我们设置等待超时的时间,预设定时间内没有事件发生时,会返回。
那么,Redis为了完成这个事件驱动过程设计了四种数据结构,是我们要在完成源码的掌握的,也是咱们在阅读核心方法中变量和传参的。所以先来了解一下。
Redis 事件驱动模型有四个主要的数据结构:aeFileEvent文件事件,aeTimeEvent时间事件,aeFiredEvent事件触发,aeEventLoop事件循环
1、aeFileEvent-文件事件
typedef struct aeFileEvent {
int mask;
aeFileProc *rfileProc;
aeFileProc *wfileProc;
void *clientData;
} aeFileEvent;
2、aeTimeEvent-时间事件
typedef struct aeTimeEvent {
long long id;
long when_sec;
long when_ms;
aeTimeProc *timeProc;
aeEventFinalizerProc *finalizerProc;
void *clientData;
struct aeTimeEvent *next;
} aeTimeEvent;
3、aeFiredEvent-触发事件
typedef struct aeFiredEvent {
int fd;
int mask;
} aeFiredEvent;
4、aeEventLoop-循环事件
typedef struct aeEventLoop {
int maxfd;
int setsize;
long long timeEventNextId;
time_t lastTime;
aeFileEvent *events;
aeFiredEvent *fired;
aeTimeEvent *timeEventHead;
int stop;
void *apidata;
aeBeforeSleepProc *beforesleep;
} aeEventLoop;
|