暗淡青春|Redis1.0源码阅读笔记一、总体流程( 二 )
static void initServer() {int j;signal(SIGHUP, SIG_IGN);signal(SIGPIPE, SIG_IGN);setupSigSegvAction();server.clients = listCreate();server.slaves = listCreate();server.monitors = listCreate();server.objfreelist = listCreate();createSharedObjects();server.el = aeCreateEventLoop();server.db = zmalloc(sizeof(redisDb)*server.dbnum);server.sharingpool = dictCreate(if (!server.db || !server.clients || !server.slaves || !server.monitors || !server.el || !server.objfreelist)oom("server initialization"); /* Fatal OOM */server.fd = anetTcpServer(server.neterr, server.port, server.bindaddr);if (server.fd == -1) {redisLog(REDIS_WARNING, "Opening TCP port: %s", server.neterr);exit(1);}for (j = 0; j < server.dbnum; j++) {server.db[j].dict = dictCreate(server.db[j].expires = dictCreate(server.db[j].id = j;}server.cronloops = 0;server.bgsaveinprogress = 0;server.bgsavechildpid = -1;server.lastsave = time(NULL);server.dirty = 0;server.usedmemory = 0;server.stat_numcommands = 0;server.stat_numconnections = 0;server.stat_starttime = time(NULL);aeCreateTimeEvent(server.el, 1000, serverCron, NULL, NULL);}aeMainaeMain是Redis处理逻辑的主循环 , 退出循环的标记是eventLoop->stop不等于零 , 具体的逻辑处理 , 是由函数aeProcessEvents完成的 。
void aeMain(aeEventLoop *eventLoop){eventLoop->stop = 0;while (!eventLoop->stop)aeProcessEvents(eventLoop, AE_ALL_EVENTS);}eventLoop是全局变量server的el字段 , 其类型是结构体aeEventLoop 。
/* State of an event based program */typedef struct aeEventLoop {long long timeEventNextId;aeFileEvent *fileEventHead;aeTimeEvent *timeEventHead;int stop;} aeEventLoop;接下来 , 我们要重点看一下函数aeProcessEvents具体做了哪些事 。
首先 , 遍历链表fileEventHead , 分别获得AE_READABLE、AE_WRITABLE、AE_EXCEPTION三类的集合 。
aeFileEvent *fe = eventLoop->fileEventHead;/* Check file events */if (flagsif (fe->maskif (fe->maskif (maxfd < fe->fd) maxfd = fe->fd;numfd++;fe = fe->next;}}接着 , 计算最近一个时间事件触发的剩余时间tv , 用该时间当做select的timeout参数
if (flags if (shortest) {long now_sec, now_ms;/* Calculate the time missing for the nearest* timer to fire. */aeGetTime(tvp =tvp->tv_sec = shortest->when_sec - now_sec;if (shortest->when_ms < now_ms) {tvp->tv_usec = ((shortest->when_ms+1000) - now_ms)*1000;tvp->tv_sec --;} else {tvp->tv_usec = (shortest->when_ms - now_ms)*1000;}} else {/* If we have to check for events but need to return* ASAP because of AE_DONT_WAIT we need to se the timeout* to zero */if (flagstvp =} else {/* Otherwise we can block */tvp = NULL; /* wait forever */}}调用select , 获得可读、可写的文件描述符数量 。 如果有可读写的文件描述符 , 则遍历eventLoop中的链表fileEventHead , 依次调用每个节点的fielProc函数 。 fileEventHead链表的每个节点 , 类型是struct aeFileEvent, 创建节点的函数是:int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData, aeEventFinalizerProc *finalizerProc) 。函数参数的proc , 指定了节点的fileProc实现 。 通过全局搜索调用函数aeCreateFileEvent的地方 , 我们可以知道 , 节点的fileProc的具体实现 , 包括以下四种:readQueryFromClient、sendReplyToClient、sendBulkToSlave、acceptHandler 。
推荐阅读
- 暗淡青春|苹果明天搞大事!新iPad、iPhone 12发布时间要来了
- Miss西里|邓伦水洗蓝牛仔搭配清爽简约 顺毛发型尽显青春气息
- 艾希大人|竹内结子拍摄杂志封面 柠檬黄上衣青春活力
- M体育地带|青春风暴!意媒排出米兰U23首发阵容
- 街拍|美女街拍:青春时尚小姐姐,黑色吊带搭配牛仔热裤,魅力十足!
- 阳婷的青春|将相和的主人翁廉颇、蔺相如最后结局如何?你真不一定知道!
- 粉笔教育带你走近90后扶贫基层,聆听“女承父志”的青春故事
- 街拍|街拍:光彩照人小姐姐,时尚的打扮,尽显青春魅力!
- 街拍|街拍:简单时尚的小姐姐,青春时尚,展现出曼妙身姿!
- 墨羽青春穿搭札记|同台比美都翻车!张靓颖暴露麒麟臂,吴昕显腿粗,喻言造型拖沓
