redis 死循环为什么CPU很低?

redis的事件循环代码

void aeMain(aeEventLoop *eventLoop) {
    eventLoop->stop = 0;
    while (!eventLoop->stop) {
        if (eventLoop->beforesleep != NULL)
            eventLoop->beforesleep(eventLoop);
        aeProcessEvents(eventLoop, AE_ALL_EVENTS);
    }
}

让我不理解的是,这是一个死循环,但是CPU占用很低。所以就看看代码学习一下。由于我只需要时间事件(processTimeEvents)。所以我将aeProcessEvents删掉了一些代码,只保留时间事件。然后CPU暴增。

微信图片_20190918182652.png

可以看到CPU从0.0涨到了90.3于是往上回溯代码。最终发现其中一个比较关键的:aeApiPoll函数。

网上有一段话:aeProcessEvents 都会先 计算最近的时间事件发生所需要等待的时间 ,然后调用 aeApiPoll 方法在这段时间中等待事件的发生,在这段时间中如果发生了文件事件,就会优先处理文件事件,否则就会一直等待,直到最近的时间事件需要触发。跟进去会发现是一个select,它是用来等待文件描述词(普通文件、终端、伪终端、管道、FIFO、套接字及其他类型的字符型)这些的改变事件。

在传递的时候会将tvp传入进来,tvp是最近发生的事件,也被设置成了select的过期事件,所以如果没有发生文件事件,然后又select又过期了,自动会走如下代码

    if (retval > 0) {
        for (j = 0; j <= eventLoop->maxfd; j++) {
            int mask = 0;
            aeFileEvent *fe = &eventLoop->events[j];
            if (fe->mask == AE_NONE) continue;
            if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds))
                mask |= AE_READABLE;
            if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds))
                mask |= AE_WRITABLE;
            eventLoop->fired[numevents].fd = j;
            eventLoop->fired[numevents].mask = mask;
            numevents++;
        }
    }

所以这里的等待就会造成while的一些时间片的释放,然后会降低CPU。


redis 死循环为什么CPU很低?


本站如无特别说明即为原创,转而告知:(http://iwonmo.com/archives/1613.html)

标签: redis while

添加新评论