什么是EventLoop
单线程就意味着,所有工作须要排队,前一个工作完结,才会执行后一个工作。如果前一个工作耗时很长,后一个工作就不得不始终等着。
如果排队是因为计算量大,CPU忙不过来,倒也算了,然而很多时候CPU是闲着的,因为IO设施(输入输出设施)很慢(比方Ajax操作从网络读取数据),不得不等着后果进去,再往下执行。
于是,所有工作能够分成两种,一种是同步工作(synchronous),另一种是异步工作(asynchronous)。同步工作指的是,在主线程上排队执行的工作,只有前一个工作执行结束,能力执行后一个工作;异步工作指的是,不进入主线程、而进入"工作队列"(task queue)的工作,只有"工作队列"告诉主线程,某个异步工作能够执行了,该工作才会进入主线程执行。
具体来说,异步执行的运行机制如下。
(1)所有同步工作都在主线程上执行,造成一个执行栈(execution context stack)。(2)主线程之外,还存在一个"工作队列"(task queue)。只有异步工作有了运行后果,就在"工作队列"之中搁置一个事件。(3)一旦"执行栈"中的所有同步工作执行结束,零碎就会读取"工作队列",看看外面有哪些事件。那些对应的异步工作,于是完结期待状态,进入执行栈,开始执行。(4)主线程一直反复下面的第三步。
redis启动后初始化工作完结后,即进入期待工作的循环过程中。aeMain函数,
ae.c/aeMain函数
void aeMain(aeEventLoop *eventLoop) { while (!eventLoop->stop) { aeProcessEvents(eventLoop, AE_ALL_EVENTS); }}
ae.h/aeEventLoop
struct aeEventLoop { int setsize; // 最大事件数量 void *apidata; // io事件数据,见ae_epoll.c/aeApiState struct aeFileEvent *events; // 注册事件列表,fd为下标,见ae.h/aeFileEvent}
ae.h/aeFileEvent
struct aeFileEvent { int mask; // one of AE_(READABLE|WRITABLE),事件类型 aeFileProc *rfileProc; // READABLE事件处理器 aeFileProc *wfileProc; // WRITABLE事件处理器 void *clientData; // 客户端数据}