redis服务器是一个事件驱动程序,分为两种事件:文件事件和时间事件。时间事件比如AOF写入与同步。
在服务器启动时,会触发事件驱动,这里直接来看看实现:
int main(int argc, char **argv) {
//...
aeSetBeforeSleepProc(server.el,beforeSleep);
aeSetAfterSleepProc(server.el,afterSleep);
aeMain(server.el);
aeDeleteEventLoop(server.el);
return 0;
}
以上是服务器启动时有关ae的操作,这里关注aeMain方法:
void aeMain(aeEventLoop *eventLoop) {
eventLoop->stop = 0;
while (!eventLoop->stop) {
if (eventLoop->beforesleep != NULL)
eventLoop->beforesleep(eventLoop);
aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP);
}
}
其中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;
aeBeforeSleepProc *aftersleep;
} aeEventLoop;
这里面包含aeFileEvent:
typedef struct aeFileEvent {
/* 记录event类型
* #define AE_NONE 0 没有事件
* #define AE_READABLE 1 触发readable事件
* #define AE_WRITABLE 2 触发writable事件
* #define AE_BARRIER 4 同一个时间循环里,触发了readable事件那么不会触发writable事件
*/
int mask;
aeFileProc *rfileProc; /* 写操作 */
aeFileProc *wfileProc; /* 读操作 */
void *clientData;
} aeFileEvent;
还包含aeFiredEvent:用来记录已触发的事件
typedef struct aeFiredEvent {
int fd;
int mask;
} aeFiredEvent;
来看看事件的调度和执行过程,也就是aeProcessEvents方法:
/* Process every pending time event, then every pending file event
* (that may be registered by time event callbacks just processed).
* Without special flags