Redis源碼解析-AE事件庫

AE事件庫

AE事件庫是Redis作者自己寫的一個(gè)輕型的異步網(wǎng)絡(luò)庫,不同于Libevent的臃腫,ae保持著它的輕量高效的特點(diǎn)。


Reactor模式

說到異步就不能不說說Reactor模式,這是廣泛應(yīng)用的一種服務(wù)端開發(fā)模式,它本著don't call us,we will call you的思想,將同步阻塞的代碼變成了基于事件回調(diào)的模式。

準(zhǔn)確的說就是有一個(gè)不斷循環(huán)的線程,這個(gè)線程會(huì)不斷的輪詢發(fā)生的事件,然后挨個(gè)處理所發(fā)生的事件,調(diào)用事件事先注冊(cè)好的回調(diào)函數(shù),這個(gè)線程就被稱作Reactor。

AE底層實(shí)現(xiàn)

ae的實(shí)現(xiàn)根據(jù)操作系統(tǒng)的不同會(huì)采用最高效的I/O多路復(fù)用機(jī)制:

/* Include the best multiplexing layer supported by this system.

* The following should be ordered by performances, descending. */

#ifdef HAVE_EPOLL

#include "ae_epoll.c"

#else

#ifdef HAVE_KQUEUE

#include "ae_kqueue.c"

#else

#include "ae_select.c"

#endif

#endif

可以看到AE優(yōu)先使用epoll>kqueue>select的順序去選擇I/O多路復(fù)用的底層實(shí)現(xiàn)。

AE主要包括的幾個(gè)部分

EventLoop

事件循環(huán),這不僅是AE,也是Redis最重要的一個(gè)部分。它是一個(gè)結(jié)構(gòu)體,里面保存著事件循環(huán)總體的信息,比如:

時(shí)間事件的鏈表頭,最大的文件描述符,sleep前要執(zhí)行的任務(wù)函數(shù)等。

事件

AE中事件分為文件事件和時(shí)間事件兩種,對(duì)于文件事件來說就是調(diào)用多路復(fù)用函數(shù)去收集到的發(fā)生的事件,對(duì)于每個(gè)文件事件,又分為讀事件和寫事件兩種,分別調(diào)用對(duì)應(yīng)的回調(diào)函數(shù)去處理他們。

而時(shí)間事件在eventLoop中以一個(gè)鏈表的形式存在,在調(diào)用多路復(fù)用函數(shù)的時(shí)候,AE會(huì)去查詢最近的一個(gè)時(shí)間事件,并用它的發(fā)生時(shí)間-當(dāng)前時(shí)間的差作為AE調(diào)用多路復(fù)用函數(shù)時(shí)的超時(shí)時(shí)間,以及時(shí)的處理要過期的時(shí)間事件。

eventLoop中的events和fired是兩塊內(nèi)存buffer,events保存所有要監(jiān)視的文件描述符,它的容量可以包含最大的文件描述符數(shù)量的文件事件信息,而fired保存所有的已發(fā)生的文件的信息。

aeMain

aeMain是AE的啟動(dòng)函數(shù),也是AE的事件循環(huán),主程序的循環(huán)也起始于這個(gè)函數(shù):

void aeMain(aeEventLoop *eventLoop) {

eventLoop->stop = 0;

while (!eventLoop->stop) {

if (eventLoop->beforesleep != NULL)

eventLoop->beforesleep(eventLoop);

aeProcessEvents(eventLoop, AE_ALL_EVENTS);

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 最近在看 UNIX 網(wǎng)絡(luò)編程并研究了一下 Redis 的實(shí)現(xiàn),感覺 Redis 的源代碼十分適合閱讀和分析,其中 ...
    Draveness閱讀 10,867評(píng)論 8 56
  • NIO(Non-blocking I/O,在Java領(lǐng)域,也稱為New I/O),是一種同步非阻塞的I/O模型,也...
    閃電是只貓閱讀 3,291評(píng)論 0 7
  • 本文是Netty文集中“Netty 那些事兒”系列的文章。主要結(jié)合在開發(fā)實(shí)戰(zhàn)中,我們遇到的一些“奇奇怪怪”的問題,...
    tomas家的小撥浪鼓閱讀 15,934評(píng)論 3 35
  • 本文摘抄自linux基礎(chǔ)編程 IO概念 Linux的內(nèi)核將所有外部設(shè)備都可以看做一個(gè)文件來操作。那么我們對(duì)與外部設(shè)...
    VD2012閱讀 1,071評(píng)論 0 2
  • 今天姑娘放學(xué)回家,我先給姑娘檢查了作業(yè),感覺姑娘比昨天寫的好了許多,不知道是不是當(dāng)媽媽自己感覺?今天老師還布置的作...
    娃娃的娘親閱讀 227評(píng)論 0 0

友情鏈接更多精彩內(nèi)容