redis 事件处理

来源:互联网 发布:淘宝网九块九包邮女装 编辑:程序博客网 时间:2024/05/16 07:16

事件处理其实很简单,下面这个函数

403 //主函数404 void aeMain(aeEventLoop *eventLoop) {405     eventLoop->stop = 0;406     while (!eventLoop->stop) {407         if (eventLoop->beforesleep != NULL)408             eventLoop->beforesleep(eventLoop);409         aeProcessEvents(eventLoop, AE_ALL_EVENTS);410     }411 }

就是不断的循环,调用 aeProcessEvents.


aeProcessEvents:

这个函数就是处理事件的,包括了时间事件和文件事件。

int aeProcessEvents(aeEventLoop *eventLoop, int flags){    int processed = 0, numevents;    /* Nothing to do? return ASAP */    if (!(flags & AE_TIME_EVENTS) && !(flags & AE_FILE_EVENTS)) return 0;    /* Note that we want call select() even if there are no     * file events to process as long as we want to process time     * events, in order to sleep until the next time event is ready     * to fire. */    //即使没有文件事件,只要有时间事件(并且 AE_DONT_WAIT), 也计算等待时间    if (eventLoop->maxfd != -1 ||        ((flags & AE_TIME_EVENTS) && !(flags & AE_DONT_WAIT))) {        int j;        aeTimeEvent *shortest = NULL;        struct timeval tv, *tvp;        //查找和现在最近的事件        if (flags & AE_TIME_EVENTS && !(flags & AE_DONT_WAIT))            shortest = aeSearchNearestTimer(eventLoop);        if (shortest) {            //最早触发事件的时间            long now_sec, now_ms;            /* Calculate the time missing for the nearest             * timer to fire. */            aeGetTime(&now_sec, &now_ms);            tvp = &tv;            tvp->tv_sec = shortest->when_sec - now_sec;            //计算时间差值,微妙不够,从秒这里拿1            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;            }            //最早触发时间已经过了,那就不需要等了            if (tvp->tv_sec < 0) tvp->tv_sec = 0;            if (tvp->tv_usec < 0) tvp->tv_usec = 0;        } 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 (flags & AE_DONT_WAIT) {                tv.tv_sec = tv.tv_usec = 0;                tvp = &tv;            } else {                /* Otherwise we can block */                tvp = NULL; /* wait forever */            }        }        //从上面计算的到在这里阻塞的时间        numevents = aeApiPoll(eventLoop, tvp);        for (j = 0; j < numevents; j++) {            aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd];            int mask = eventLoop->fired[j].mask;            int fd = eventLoop->fired[j].fd;            int rfired = 0;            /* note the fe->mask & mask & ... code: maybe an already processed             * event removed an element that fired and we still didn't             * processed, so we check if the event is still valid. */            if (fe->mask & mask & AE_READABLE) {                rfired = 1;                fe->rfileProc(eventLoop,fd,fe->clientData,mask);            }            if (fe->mask & mask & AE_WRITABLE) {                if (!rfired || fe->wfileProc != fe->rfileProc)                    fe->wfileProc(eventLoop,fd,fe->clientData,mask);            }            processed++;        }    }    /* Check time events */    if (flags & AE_TIME_EVENTS)        processed += processTimeEvents(eventLoop);    return processed; /* return the number of processed file/time events */}

我们可以把主程序当作是一个开车的父亲,时间事件是接女儿放学,文件事件是去车站接客人赚钱。

那么AE_DONT_WAIT可以理解为不能在车站停靠。


1 首先决定是否需要计算在车站等待时间:

           if (eventLoop->maxfd != -1 ||
                 ((flags & AE_TIME_EVENTS) && !(flags & AE_DONT_WAIT))) 

           需要满足下面任何一个条件:

            一   有客人会出现

            二  今天要去接女儿  并且 车站允许停靠车子


2 计算女儿放学时间:

           如果今天上学,

                    那么就得到放学时间,和当前时间比较,如果还没有到,那么再等等,到了就不要等了

           如果不上学,那么就只要处理乘客,如果车站不让听,马上走,如果给停,一定等待乘客出现


3 把乘客送过去(如果有)


4 送女儿回家(如果上学)








原创粉丝点击