Linux面試必知: 一句話講透epoll

1. epoll概念

在Linux的Man文檔中狠角,我們可以看到如下定義

Epoll - I/O event notification facility
epoll是一種I/O事件通知機(jī)制

I/O事件

  • I/O
    輸入輸出(input/output),輸入輸出的對(duì)象可以是 文件(file), 網(wǎng)絡(luò)(socket), 進(jìn)程之間的管道(pipe), 在linux系統(tǒng)中病涨,都用文件描述符(fd)來表示

  • 事件

    • 可讀事件蚁滋, 當(dāng)文件描述符關(guān)聯(lián)的內(nèi)核讀緩沖區(qū)可讀,則觸發(fā)可讀事件
      什么是可讀呢? 就是內(nèi)核緩沖區(qū)非空窿锉,有數(shù)據(jù)可以讀取
    • 可寫事件, 當(dāng)文件描述符關(guān)聯(lián)的內(nèi)核寫緩沖區(qū)可寫,則觸發(fā)可寫事件
      什么是可寫呢膝舅?就是內(nèi)核緩沖區(qū)不滿嗡载,有空閑空間可以寫入

通知機(jī)制

  • 通知機(jī)制,就是當(dāng)事件發(fā)生的時(shí)候仍稀,去通知他
  • 通知機(jī)制的反面洼滚,就是輪詢機(jī)制

以上兩點(diǎn)結(jié)合起來理解

epoll是一種當(dāng)文件描述符的內(nèi)核緩沖區(qū)非空的時(shí)候,發(fā)出可讀信號(hào)進(jìn)行通知技潘,當(dāng)寫緩沖區(qū)不滿的時(shí)候遥巴,發(fā)出可寫信號(hào)通知的機(jī)制

2. 水平觸發(fā)與邊緣觸發(fā)

水平觸發(fā)(level-trggered)

  • 只要文件描述符關(guān)聯(lián)的讀內(nèi)核緩沖區(qū)非空,有數(shù)據(jù)可以讀取享幽,就一直發(fā)出可讀信號(hào)進(jìn)行通知铲掐,
  • 當(dāng)文件描述符關(guān)聯(lián)的內(nèi)核寫緩沖區(qū)不滿,有空間可以寫入值桩,就一直發(fā)出可寫信號(hào)進(jìn)行通知

邊緣觸發(fā)(edge-triggered)

  • 當(dāng)文件描述符關(guān)聯(lián)的讀內(nèi)核緩沖區(qū)由空轉(zhuǎn)化為非空的時(shí)候摆霉,則發(fā)出可讀信號(hào)進(jìn)行通知,
  • 當(dāng)文件描述符關(guān)聯(lián)的內(nèi)核寫緩沖區(qū)由滿轉(zhuǎn)化為不滿的時(shí)候奔坟,則發(fā)出可寫信號(hào)進(jìn)行通知

兩者的區(qū)別在哪里呢携栋?水平觸發(fā)是只要讀緩沖區(qū)有數(shù)據(jù),就會(huì)一直觸發(fā)可讀信號(hào)咳秉,而邊緣觸發(fā)僅僅在空變?yōu)榉强盏臅r(shí)候通知一次婉支,舉個(gè)例子:

  1. 讀緩沖區(qū)剛開始是空的
  2. 讀緩沖區(qū)寫入2KB數(shù)據(jù)
  3. 水平觸發(fā)和邊緣觸發(fā)模式此時(shí)都會(huì)發(fā)出可讀信號(hào)
  4. 收到信號(hào)通知后,讀取了1kb的數(shù)據(jù)澜建,讀緩沖區(qū)還剩余1KB數(shù)據(jù)
  5. 水平觸發(fā)會(huì)再次進(jìn)行通知向挖,而邊緣觸發(fā)不會(huì)再進(jìn)行通知

所以邊緣觸發(fā)需要一次性的把緩沖區(qū)的數(shù)據(jù)讀完為止,也就是一直讀炕舵,直到讀到EGAIN為止户誓,EGAIN說明緩沖區(qū)已經(jīng)空了,因?yàn)檫@一點(diǎn)幕侠,邊緣觸發(fā)需要設(shè)置文件句柄為非阻塞

//水平觸發(fā)
    ret = read(fd, buf, sizeof(buf));
    
    //邊緣觸發(fā)
    while(true) {
        ret = read(fd, buf, sizeof(buf);
        if (ret == EAGAIN) break;
    }

3. epoll接口介紹

  • epoll_create

    • 創(chuàng)建epoll實(shí)例帝美,會(huì)創(chuàng)建所需要的紅黑樹,以及就緒鏈表,以及代表epoll實(shí)例的文件句柄

      int epoll_create(int size);
      Man文檔中說明了在老的內(nèi)核版本中悼潭,入?yún)ize用來指出創(chuàng)建的內(nèi)部數(shù)據(jù)結(jié)構(gòu)的大小庇忌,目前已經(jīng)可以動(dòng)態(tài)調(diào)整,但是為了兼容老的版本舰褪,所以仍然保留皆疹,這個(gè)size其實(shí)意義已經(jīng)不大

  • epoll_ctl

    • 添加,修改占拍,或者刪除 注冊(cè)到epoll實(shí)例中的文件描述符上的監(jiān)控事件

      int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
      對(duì)于添加到epfd的文件描述符fd, 添加或者刪除或者修改略就, 對(duì)應(yīng)的event

      • epfd: 通過epoll_create創(chuàng)建的文件描述符
      • op:操作類型
        EPOLL_CTL_ADD, 為相應(yīng)fd添加事件
        EPOLL_CTL_MOD, 修改fd的事件
        EPOLL_CTL_DEL,刪除fd上的某些事件
      • fd: 操作的目標(biāo)文件描述符
      • event: 要操作的事件
         typedef union epoll_data {
            void  *ptr;
            int  fd;
            uint32_t     u32;
            uint64_t     u64;
        } epoll_data_t;
          
        struct epoll_event {
            uint32_t  events;      /* Epoll events */
            epoll_data_t data;        /* User data variable */
        };
        
          events可以是一組bit的組合
              EPOLLIN:可讀
              EPOLLOUT: 可寫
              EPOLLET: 邊緣觸發(fā)晃酒,默認(rèn)是水平觸發(fā)
        
  • epoll_wait

    int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
    等待注冊(cè)的事件發(fā)生表牢,返回事件的數(shù)目,并將觸發(fā)的事件寫入events數(shù)組中

    • epfd: epoll實(shí)例文件描述符
    • events: 數(shù)組出參贝次,用來記錄被觸發(fā)的events崔兴,其大小應(yīng)該和maxevents一致
    • maxevents: 返回的events的最大個(gè)數(shù),如果最大個(gè)數(shù)大于實(shí)際觸發(fā)的個(gè)數(shù)蛔翅,則下次epoll_wait的時(shí)候仍然可以返回
    • timeout: 等待事件敲茄,毫秒為單位 -1:無限等待 0:立即返回

了解以上這些,面試是足夠了山析,但是對(duì)于工程中的實(shí)際使用堰燎,仍然不足,后續(xù)會(huì)以epoll在redis中的使用為例笋轨,為大家進(jìn)行剖析

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秆剪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子翩腐,更是在濱河造成了極大的恐慌鸟款,老刑警劉巖膏燃,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茂卦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡组哩,警方通過查閱死者的電腦和手機(jī)等龙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來伶贰,“玉大人蛛砰,你說我怎么就攤上這事∈蜓茫” “怎么了泥畅?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)琅翻。 經(jīng)常有香客問我位仁,道長(zhǎng)柑贞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任聂抢,我火速辦了婚禮钧嘶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘琳疏。我一直安慰自己有决,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布空盼。 她就那樣靜靜地躺著书幕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪我注。 梳的紋絲不亂的頭發(fā)上按咒,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音但骨,去河邊找鬼励七。 笑死,一個(gè)胖子當(dāng)著我的面吹牛奔缠,可吹牛的內(nèi)容都是我干的掠抬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼校哎,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼两波!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起闷哆,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤腰奋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后抱怔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體劣坊,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年屈留,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了局冰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡灌危,死狀恐怖康二,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情勇蝙,我是刑警寧澤沫勿,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響产雹,放射性物質(zhì)發(fā)生泄漏烫罩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一洽故、第九天 我趴在偏房一處隱蔽的房頂上張望贝攒。 院中可真熱鬧,春花似錦时甚、人聲如沸隘弊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)梨熙。三九已至,卻和暖如春刀诬,著一層夾襖步出監(jiān)牢的瞬間咽扇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工陕壹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留质欲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓糠馆,卻偏偏與公主長(zhǎng)得像嘶伟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子又碌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容