Redis源码解析-AE事件库

AE事件库

AE事件库是Redis作者自己写的一个轻型的异步网络库,不同于Libevent的臃肿,ae保持着它的轻量高效的特点。


Reactor模式

说到异步就不能不说说Reactor模式,这是广泛应用的一种服务端开发模式,它本着don't call us,we will call you的思想,将同步阻塞的代码变成了基于事件回调的模式。

准确的说就是有一个不断循环的线程,这个线程会不断的轮询发生的事件,然后挨个处理所发生的事件,调用事件事先注册好的回调函数,这个线程就被称作Reactor。

AE底层实现

ae的实现根据操作系统的不同会采用最高效的I/O多路复用机制:

/* Include the best multiplexing layer supported by this system.

* The following should be ordered by performances, descending. */

#ifdef HAVE_EPOLL

#include "ae_epoll.c"

#else

#ifdef HAVE_KQUEUE

#include "ae_kqueue.c"

#else

#include "ae_select.c"

#endif

#endif

可以看到AE优先使用epoll>kqueue>select的顺序去选择I/O多路复用的底层实现。

AE主要包括的几个部分

EventLoop

事件循环,这不仅是AE,也是Redis最重要的一个部分。它是一个结构体,里面保存着事件循环总体的信息,比如:

时间事件的链表头,最大的文件描述符,sleep前要执行的任务函数等。

事件

AE中事件分为文件事件和时间事件两种,对于文件事件来说就是调用多路复用函数去收集到的发生的事件,对于每个文件事件,又分为读事件和写事件两种,分别调用对应的回调函数去处理他们。

而时间事件在eventLoop中以一个链表的形式存在,在调用多路复用函数的时候,AE会去查询最近的一个时间事件,并用它的发生时间-当前时间的差作为AE调用多路复用函数时的超时时间,以及时的处理要过期的时间事件。

eventLoop中的events和fired是两块内存buffer,events保存所有要监视的文件描述符,它的容量可以包含最大的文件描述符数量的文件事件信息,而fired保存所有的已发生的文件的信息。

aeMain

aeMain是AE的启动函数,也是AE的事件循环,主程序的循环也起始于这个函数:

void aeMain(aeEventLoop *eventLoop) {

eventLoop->stop = 0;

while (!eventLoop->stop) {

if (eventLoop->beforesleep != NULL)

eventLoop->beforesleep(eventLoop);

aeProcessEvents(eventLoop, AE_ALL_EVENTS);

}

}

你可能感兴趣的:(Redis源码解析-AE事件库)