博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Redis中的事件处理模型
阅读量:6121 次
发布时间:2019-06-21

本文共 2016 字,大约阅读时间需要 6 分钟。

Redis并没有使用libevent,libev,libuv等事件IO库,而是通过ae.h、ae.c两个文件,封装了简单的事件处理模型。进一步地,事件处理需要使用到系统的select、epoll等函数,在ae.c中,通过简单的宏判断,引入相应的实现文件,分别是ae_epoll.c、ae_evport.c、ae_kqueue.c和ae_select.c。

先来看下ae.h。首先,Redis定义了两种事件类型,分别是aeFileEventaeTimeEvent,前者针对文件IO(包含网络)。后者主要是一些定时或周期运行的函数,比如serverCron()

最主要的数据结构是struct aeEventLoop。ae.h对外提供的方法,几乎都以此结构的实例为操作对象。

typedef struct aeEventLoop {    int maxfd;   /* highest file descriptor currently registered */    int setsize; /* max number of file descriptors tracked */    long long timeEventNextId;    time_t lastTime;     /* Used to detect system clock skew */    aeFileEvent *events; /* Registered events */    aeFiredEvent *fired; /* Fired events */    aeTimeEvent *timeEventHead;    int stop;    void *apidata; /* This is used for polling API specific data */    aeBeforeSleepProc *beforesleep;    aeBeforeSleepProc *aftersleep;} aeEventLoop;

maxfd记录当前跟踪的最大文件描述符,在调用某些api时便于使用,比如select()需要给一个maxfd+1的参数。

setsize是能处理的文件描述符的最大数量。后面可以看到这个数量关系到eventsfired的内存分配大小。

另外一个比较重要的是apidata,其实是指向了具体的事件处理模型相关的一个状态数据(aeApiState)。如果使用的是select,那么状态数据包含了不同的fd_set;如果使用的是epoll,状态数据包含了epoll_create()返回的fd,还有用于接收epoll_wait()返回的存在可用事件的列表events。

aeCreateEventLoop()便是创建aeEventLoop的实例。在这里可以看到,针对文件IO,eventsfired是通过固定连续分配,按照数组的方式来使用。针对时间事件,则是timeEventHead这样的一个链表。

另外,再通过调用aeApiCreate()来这是apidata。按照使用的不同的系统事件处理机制,aeApiCreate()的实现是不同的。取决于如下这段代码:

#ifdef HAVE_EVPORT#include "ae_evport.c"#else    #ifdef HAVE_EPOLL    #include "ae_epoll.c"    #else        #ifdef HAVE_KQUEUE        #include "ae_kqueue.c"        #else        #include "ae_select.c"        #endif    #endif#endif

一般来说,这些HAVE_开头的宏,是通过configure(GNU autoconf automake系统工具生成),或者cmake判断当前系统环境并进行定义的。但是Redis并没有使用什么复杂的构建工具,只有一个Makefile,这些宏是在src/config.h中,根据操作系统或编译器提供的宏进行判断并进行定义。

具体调用的地方,比如src/server.c中,先进行

server.el = aeCreateEventLoop(server.maxclients+CONFIG_FDSET_INCR);

创建了aeEventLoop

之后便可以注册定时任务:

if (aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL) == AE_ERR) {        serverPanic("Can't create event loop timers.");        exit(1);    }

转载地址:http://kjqka.baihongyu.com/

你可能感兴趣的文章
【支持iOS11】UITableView左滑删除自定义 - 实现多选项并使用自定义图片
查看>>
day6-if,while,for的快速掌握
查看>>
JavaWeb学习笔记(十四)--JSP语法
查看>>
【算法笔记】多线程斐波那契数列
查看>>
java8函数式编程实例
查看>>
jqgrid滚动条宽度/列显示不全问题
查看>>
在mac OS10.10下安装 cocoapods遇到的一些问题
查看>>
angularjs表达式中的HTML内容,如何不转义,直接表现为html元素
查看>>
css技巧
查看>>
Tyvj 1728 普通平衡树
查看>>
[Usaco2015 dec]Max Flow
查看>>
javascript性能优化
查看>>
多路归并排序之败者树
查看>>
java连接MySql数据库
查看>>
转:Vue keep-alive实践总结
查看>>
android studio修改新项目package名称
查看>>
深入python的set和dict
查看>>
C++ 11 lambda
查看>>
Hadoop2.5.0 搭建实录
查看>>
实验吧 recursive write up
查看>>