IO多路復(fù)用之select、poll慧妄、epoll詳解lw

IO多路復(fù)用之select顷牌、poll、epoll詳解

目前支持I/O多路復(fù)用的系統(tǒng)調(diào)用有select塞淹,pselect韧掩,poll,epoll窖铡,I/O多路復(fù)用就是通過(guò)一種機(jī)制,一個(gè)進(jìn)程可以監(jiān)視多個(gè)描述符坊谁,一旦某個(gè)描述符就緒(一般是讀就緒或者寫(xiě)就緒)费彼,能夠通知程序進(jìn)行相應(yīng)的讀寫(xiě)操作。但select口芍,pselect箍铲,poll,epoll本質(zhì)上都是同步I/O鬓椭,因?yàn)樗麄兌夹枰谧x寫(xiě)事件就緒后自己負(fù)責(zé)進(jìn)行讀寫(xiě)颠猴,也就是說(shuō)這個(gè)讀寫(xiě)過(guò)程是阻塞的,而異步I/O則無(wú)需自己負(fù)責(zé)進(jìn)行讀寫(xiě)小染,異步I/O的實(shí)現(xiàn)會(huì)負(fù)責(zé)把數(shù)據(jù)從內(nèi)核拷貝到用戶空間翘瓮。

與多進(jìn)程和多線程技術(shù)相比,I/O多路復(fù)用技術(shù)的最大優(yōu)勢(shì)是系統(tǒng)開(kāi)銷(xiāo)小裤翩,系統(tǒng)不必創(chuàng)建進(jìn)程/線程资盅,也不必維護(hù)這些進(jìn)程/線程,從而大大減小了系統(tǒng)的開(kāi)銷(xiāo)踊赠。


一呵扛、使用場(chǎng)景

IO多路復(fù)用是指內(nèi)核一旦發(fā)現(xiàn)進(jìn)程指定的一個(gè)或者多個(gè)IO條件準(zhǔn)備讀取,它就通知該進(jìn)程筐带。IO多路復(fù)用適用如下場(chǎng)合:

  1)當(dāng)客戶處理多個(gè)描述符時(shí)(一般是交互式輸入和網(wǎng)絡(luò)套接口)今穿,必須使用I/O復(fù)用。

  2)當(dāng)一個(gè)客戶同時(shí)處理多個(gè)套接口時(shí)伦籍,這種情況是可能的蓝晒,但很少出現(xiàn)。

  3)如果一個(gè)TCP服務(wù)器既要處理監(jiān)聽(tīng)套接口鸽斟,又要處理已連接套接口拔创,一般也要用到I/O復(fù)用。

  4)如果一個(gè)服務(wù)器即要處理TCP富蓄,又要處理UDP剩燥,一般要使用I/O復(fù)用。

  5)如果一個(gè)服務(wù)器要處理多個(gè)服務(wù)或多個(gè)協(xié)議,一般要使用I/O復(fù)用灭红。


二侣滩、select、poll变擒、epoll簡(jiǎn)介

epoll跟select都能提供多路I/O復(fù)用的解決方案君珠。在現(xiàn)在的Linux內(nèi)核里有都能夠支持,其中epoll是Linux所特有娇斑,而select則應(yīng)該是POSIX所規(guī)定策添,一般操作系統(tǒng)均有實(shí)現(xiàn)。

1毫缆、select

基本原理:select 函數(shù)監(jiān)視的文件描述符分3類(lèi)唯竹,分別是writefds、readfds苦丁、和exceptfds浸颓。調(diào)用后select函數(shù)會(huì)阻塞,直到有描述符就緒(有數(shù)據(jù) 可讀旺拉、可寫(xiě)产上、或者有except),或者超時(shí)(timeout指定等待時(shí)間蛾狗,如果立即返回設(shè)為null即可)晋涣,函數(shù)返回。當(dāng)select函數(shù)返回后沉桌,可以通過(guò)遍歷fdset姻僧,來(lái)找到就緒的描述符。


基本流程蒲牧,如圖所示:


select目前幾乎在所有的平臺(tái)上支持撇贺,其良好跨平臺(tái)支持也是它的一個(gè)優(yōu)點(diǎn)。select的一個(gè)缺點(diǎn)在于單個(gè)進(jìn)程能夠監(jiān)視的文件描述符的數(shù)量存在最大限制冰抢,在Linux上一般為1024松嘶,可以通過(guò)修改宏定義甚至重新編譯內(nèi)核的方式提升這一限制,但是這樣也會(huì)造成效率的降低挎扰。


select本質(zhì)上是通過(guò)設(shè)置或者檢查存放fd標(biāo)志位的數(shù)據(jù)結(jié)構(gòu)來(lái)進(jìn)行下一步處理翠订。這樣所帶來(lái)的缺點(diǎn)是:

1、select最大的缺陷就是單個(gè)進(jìn)程所打開(kāi)的FD是有一定限制的遵倦,它由FD_SETSIZE設(shè)置尽超,默認(rèn)值是1024

一般來(lái)說(shuō)這個(gè)數(shù)目和系統(tǒng)內(nèi)存關(guān)系很大梧躺,具體數(shù)目可以cat /proc/sys/fs/file-max察看似谁。32位機(jī)默認(rèn)是1024個(gè)傲绣。64位機(jī)默認(rèn)是2048.

2、對(duì)socket進(jìn)行掃描時(shí)是線性掃描巩踏,即采用輪詢的方法秃诵,效率較低。

當(dāng)套接字比較多的時(shí)候塞琼,每次select()都要通過(guò)遍歷FD_SETSIZE個(gè)Socket來(lái)完成調(diào)度菠净,不管哪個(gè)Socket是活躍的,都遍歷一遍彪杉。這會(huì)浪費(fèi)很多CPU時(shí)間毅往。如果能給套接字注冊(cè)某個(gè)回調(diào)函數(shù),當(dāng)他們活躍時(shí)派近,自動(dòng)完成相關(guān)操作煞抬,那就避免了輪詢,這正是epoll與kqueue做的构哺。

3、需要維護(hù)一個(gè)用來(lái)存放大量fd的數(shù)據(jù)結(jié)構(gòu)战坤,這樣會(huì)使得用戶空間和內(nèi)核空間在傳遞該結(jié)構(gòu)時(shí)復(fù)制開(kāi)銷(xiāo)大曙强。


2、poll

基本原理:poll本質(zhì)上和select沒(méi)有區(qū)別途茫,它將用戶傳入的數(shù)組拷貝到內(nèi)核空間碟嘴,然后查詢每個(gè)fd對(duì)應(yīng)的設(shè)備狀態(tài),如果設(shè)備就緒則在設(shè)備等待隊(duì)列中加入一項(xiàng)并繼續(xù)遍歷囊卜,如果遍歷完所有fd后沒(méi)有發(fā)現(xiàn)就緒設(shè)備娜扇,則掛起當(dāng)前進(jìn)程,直到設(shè)備就緒或者主動(dòng)超時(shí)栅组,被喚醒后它又要再次遍歷fd雀瓢。這個(gè)過(guò)程經(jīng)歷了多次無(wú)謂的遍歷。


它沒(méi)有最大連接數(shù)的限制玉掸,原因是它是基于鏈表來(lái)存儲(chǔ)的刃麸,但是同樣有一個(gè)缺點(diǎn):

1)大量的fd的數(shù)組被整體復(fù)制于用戶態(tài)和內(nèi)核地址空間之間,而不管這樣的復(fù)制是不是有意義司浪。

2)poll還有一個(gè)特點(diǎn)是“水平觸發(fā)”泊业,如果報(bào)告了fd后,沒(méi)有被處理啊易,那么下次poll時(shí)會(huì)再次報(bào)告該fd吁伺。


注意:從上面看,select和poll都需要在返回后租谈,通過(guò)遍歷文件描述符來(lái)獲取已經(jīng)就緒的socket篮奄。事實(shí)上,同時(shí)連接的大量客戶端在一時(shí)刻可能只有很少的處于就緒狀態(tài),因此隨著監(jiān)視的描述符數(shù)量的增長(zhǎng)宦搬,其效率也會(huì)線性下降牙瓢。


3、epoll

epoll是在2.6內(nèi)核中提出的间校,是之前的select和poll的增強(qiáng)版本矾克。相對(duì)于select和poll來(lái)說(shuō),epoll更加靈活憔足,沒(méi)有描述符限制胁附。epoll使用一個(gè)文件描述符管理多個(gè)描述符,將用戶關(guān)系的文件描述符的事件存放到內(nèi)核的一個(gè)事件表中滓彰,這樣在用戶空間和內(nèi)核空間的copy只需一次控妻。


基本原理:epoll支持水平觸發(fā)和邊緣觸發(fā),最大的特點(diǎn)在于邊緣觸發(fā)揭绑,它只告訴進(jìn)程哪些fd剛剛變?yōu)榫途w態(tài)弓候,并且只會(huì)通知一次。還有一個(gè)特點(diǎn)是他匪,epoll使用“事件”的就緒通知方式菇存,通過(guò)epoll_ctl注冊(cè)fd,一旦該fd就緒邦蜜,內(nèi)核就會(huì)采用類(lèi)似callback的回調(diào)機(jī)制來(lái)激活該fd依鸥,epoll_wait便可以收到通知。


epoll的優(yōu)點(diǎn):

1悼沈、沒(méi)有最大并發(fā)連接的限制贱迟,能打開(kāi)的FD的上限遠(yuǎn)大于1024(1G的內(nèi)存上能監(jiān)聽(tīng)約10萬(wàn)個(gè)端口)。

2絮供、效率提升衣吠,不是輪詢的方式,不會(huì)隨著FD數(shù)目的增加效率下降壤靶。

只有活躍可用的FD才會(huì)調(diào)用callback函數(shù)蒸播;即Epoll最大的優(yōu)點(diǎn)就在于它只管你“活躍”的連接,而跟連接總數(shù)無(wú)關(guān)萍肆,因此在實(shí)際的網(wǎng)絡(luò)環(huán)境中袍榆,Epoll的效率就會(huì)遠(yuǎn)遠(yuǎn)高于select和poll。

3塘揣、內(nèi)存拷貝包雀,利用mmap()文件映射內(nèi)存加速與內(nèi)核空間的消息傳遞;即epoll使用mmap減少?gòu)?fù)制開(kāi)銷(xiāo)亲铡。


epoll對(duì)文件描述符的操作有兩種模式:LT(level trigger)和ET(edge trigger)才写。LT模式是默認(rèn)模式葡兑,LT模式與ET模式的區(qū)別如下:

LT模式:當(dāng)epoll_wait檢測(cè)到描述符事件發(fā)生并將此事件通知應(yīng)用程序,應(yīng)用程序可以不立即處理該事件赞草。下次調(diào)用epoll_wait時(shí)讹堤,會(huì)再次響應(yīng)應(yīng)用程序并通知此事件。

ET模式:當(dāng)epoll_wait檢測(cè)到描述符事件發(fā)生并將此事件通知應(yīng)用程序厨疙,應(yīng)用程序必須立即處理該事件洲守。如果不處理,下次調(diào)用epoll_wait時(shí)沾凄,不會(huì)再次響應(yīng)應(yīng)用程序并通知此事件梗醇。

1、LT模式

  LT(level triggered)是缺省的工作方式撒蟀,并且同時(shí)支持block和no-block socket叙谨。在這種做法中,內(nèi)核告訴你一個(gè)文件描述符是否就緒了保屯,然后你可以對(duì)這個(gè)就緒的fd進(jìn)行IO操作手负。如果你不作任何操作,內(nèi)核還是會(huì)繼續(xù)通知你的姑尺。

2竟终、ET模式

  ET(edge-triggered)是高速工作方式,只支持no-block socket股缸。在這種模式下,當(dāng)描述符從未就緒變?yōu)榫途w時(shí)吱雏,內(nèi)核通過(guò)epoll告訴你敦姻。然后它會(huì)假設(shè)你知道文件描述符已經(jīng)就緒,并且不會(huì)再為那個(gè)文件描述符發(fā)送更多的就緒通知歧杏,直到你做了某些操作導(dǎo)致那個(gè)文件描述符不再為就緒狀態(tài)了(比如镰惦,你在發(fā)送,接收或者接收請(qǐng)求犬绒,或者發(fā)送接收的數(shù)據(jù)少于一定量時(shí)導(dǎo)致了一個(gè)EWOULDBLOCK 錯(cuò)誤)旺入。但是請(qǐng)注意,如果一直不對(duì)這個(gè)fd作IO操作(從而導(dǎo)致它再次變成未就緒)凯力,內(nèi)核不會(huì)發(fā)送更多的通知(only once)茵瘾。

  ET模式在很大程度上減少了epoll事件被重復(fù)觸發(fā)的次數(shù),因此效率要比LT模式高咐鹤。epoll工作在ET模式的時(shí)候拗秘,必須使用非阻塞套接口,以避免由于一個(gè)文件句柄的阻塞讀/阻塞寫(xiě)操作把處理多個(gè)文件描述符的任務(wù)餓死祈惶。

3雕旨、在select/poll中扮匠,進(jìn)程只有在調(diào)用一定的方法后,內(nèi)核才對(duì)所有監(jiān)視的文件描述符進(jìn)行掃描凡涩,而epoll事先通過(guò)epoll_ctl()來(lái)注冊(cè)一個(gè)文件描述符棒搜,一旦基于某個(gè)文件描述符就緒時(shí),內(nèi)核會(huì)采用類(lèi)似callback的回調(diào)機(jī)制活箕,迅速激活這個(gè)文件描述符力麸,當(dāng)進(jìn)程調(diào)用epoll_wait()時(shí)便得到通知。(此處去掉了遍歷文件描述符讹蘑,而是通過(guò)監(jiān)聽(tīng)回調(diào)的的機(jī)制末盔。這正是epoll的魅力所在。)

注意:如果沒(méi)有大量的idle-connection或者dead-connection座慰,epoll的效率并不會(huì)比select/poll高很多陨舱,但是當(dāng)遇到大量的idle-connection,就會(huì)發(fā)現(xiàn)epoll的效率大大高于select/poll版仔。


三游盲、select、poll蛮粮、epoll區(qū)別

1益缎、支持一個(gè)進(jìn)程所能打開(kāi)的最大連接數(shù)

2、FD劇增后帶來(lái)的IO效率問(wèn)題

3然想、消息傳遞方式


綜上莺奔,在選擇select,poll变泄,epoll時(shí)要根據(jù)具體的使用場(chǎng)合以及這三種方式的自身特點(diǎn):

1令哟、表面上看epoll的性能最好,但是在連接數(shù)少并且連接都十分活躍的情況下妨蛹,select和poll的性能可能比epoll好屏富,畢竟epoll的通知機(jī)制需要很多函數(shù)回調(diào)。

2蛙卤、select低效是因?yàn)槊看嗡夹枰喸兒莅搿5托б彩窍鄬?duì)的,視情況而定颤难,也可通過(guò)良好的設(shè)計(jì)改善神年。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市行嗤,隨后出現(xiàn)的幾起案子瘤袖,更是在濱河造成了極大的恐慌,老刑警劉巖昂验,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捂敌,死亡現(xiàn)場(chǎng)離奇詭異艾扮,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)占婉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)泡嘴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人逆济,你說(shuō)我怎么就攤上這事酌予。” “怎么了奖慌?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵抛虫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我简僧,道長(zhǎng)建椰,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任岛马,我火速辦了婚禮棉姐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘啦逆。我一直安慰自己伞矩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布夏志。 她就那樣靜靜地躺著乃坤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沟蔑。 梳的紋絲不亂的頭發(fā)上湿诊,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音溉贿,去河邊找鬼枫吧。 笑死浦旱,一個(gè)胖子當(dāng)著我的面吹牛宇色,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播颁湖,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼宣蠕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了甥捺?” 一聲冷哼從身側(cè)響起抢蚀,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎镰禾,沒(méi)想到半個(gè)月后皿曲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體唱逢,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屋休,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了劫樟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡叠艳,死狀恐怖奶陈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情附较,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布声搁,位于F島的核電站,受9級(jí)特大地震影響捕发,放射性物質(zhì)發(fā)生泄漏疏旨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一扎酷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧法挨,春花似錦、人聲如沸凡纳。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)暴氏。三九已至,卻和暖如春答渔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宋雏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留磨总,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓招狸,卻偏偏與公主長(zhǎng)得像邻薯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子厕诡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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