IO多路復(fù)合之select盖桥,poll,epoll

前言:

1题翻、什么是IO多路復(fù)用:

隨著網(wǎng)絡(luò)需求的增大揩徊,對(duì)于網(wǎng)絡(luò)服務(wù)性能的要求也越來(lái)越高,而這也逐步促進(jìn)了IO模型的發(fā)展嵌赠。

最初的IO模型是阻塞式的塑荒,就是在數(shù)據(jù)沒(méi)有準(zhǔn)備好的時(shí)候,進(jìn)程處于阻塞狀態(tài)姜挺,屁事不干齿税。

然后程序猿就想:我靠,這小子(暫時(shí)叫recvfrom吧)這是占著茅坑不拉屎呀炊豪,得讓他出去干點(diǎn)其他活凌箕。于是就出現(xiàn)了非阻塞式IO。

非阻塞式IO就是在進(jìn)程之中不斷的詢問(wèn)fd词渤,看數(shù)據(jù)有沒(méi)有準(zhǔn)備好牵舱,如果沒(méi)有準(zhǔn)備好,那么先去干其他事缺虐,然后過(guò)一會(huì)再來(lái)問(wèn)數(shù)據(jù)有沒(méi)有準(zhǔn)備好芜壁,這就解決了進(jìn)程“偷懶”的問(wèn)題。

但是后來(lái)發(fā)現(xiàn)那個(gè)進(jìn)程每天累死累活的,也就只能監(jiān)控一個(gè)IO沿盅,而且是不管有沒(méi)有準(zhǔn)備好都去訪問(wèn)把篓,大家都知道系統(tǒng)調(diào)用很耗時(shí)間,這樣每次去詢問(wèn)腰涧,而且還沒(méi)有數(shù)據(jù)的情況下很耗cpu資源韧掩。有沒(méi)有辦法讓他同時(shí)監(jiān)控多個(gè)IO(老板壓榨程序猿,程序猿壓榨系統(tǒng))窖铡,有數(shù)據(jù)準(zhǔn)備好才返回疗锐?

于是就請(qǐng)了個(gè)職業(yè)經(jīng)理人,當(dāng)然,這種職業(yè)經(jīng)理人也有三種费彼,分別是select()滑臊,poll(),epoll()箍铲,請(qǐng)誰(shuí)好后面再說(shuō)雇卷,請(qǐng)來(lái)先讓他循環(huán)詢問(wèn)是否有IO準(zhǔn)備好數(shù)據(jù),準(zhǔn)備好就立馬通知原來(lái)的那個(gè)recvfrom颠猴,讓他做相應(yīng)的處理关划,沒(méi)有準(zhǔn)備好就進(jìn)行阻塞。這就是IO的多路復(fù)用

IO多路復(fù)用好處在于可以不用去創(chuàng)建和維護(hù)多個(gè)線程/進(jìn)程翘瓮,用一個(gè)線程/進(jìn)程來(lái)去監(jiān)控多個(gè)IO流贮折,減小了系統(tǒng)的開(kāi)銷

2、select()

select原理:

select會(huì)在內(nèi)核中不斷詢問(wèn)數(shù)據(jù)是否準(zhǔn)備好资盅,如果沒(méi)有準(zhǔn)備好的數(shù)據(jù)调榄,就將進(jìn)程阻塞,直到有一個(gè)或者多個(gè)IO數(shù)據(jù)準(zhǔn)備好后呵扛,告訴recvfrom每庆,叫他來(lái)對(duì)數(shù)據(jù)進(jìn)行讀寫(xiě)。具體過(guò)程如下

image.png

當(dāng)我們調(diào)用select()時(shí):

1今穿、上下文切換轉(zhuǎn)換為內(nèi)核態(tài)

2扣孟、將fd從用戶空間復(fù)制到內(nèi)核空間

3、內(nèi)核遍歷所有fd荣赶,查看其對(duì)應(yīng)事件是否發(fā)生

4、如果沒(méi)發(fā)生鸽斟,將進(jìn)程阻塞拔创,當(dāng)設(shè)備驅(qū)動(dòng)產(chǎn)生中斷或者timeout時(shí)間后,將進(jìn)程喚醒富蓄,再次進(jìn)行遍歷

5剩燥、返回遍歷后的fd

6、將fd從內(nèi)核空間復(fù)制到用戶空間

但是聰明的你一定會(huì)發(fā)現(xiàn)幾個(gè)問(wèn)題:

第一:當(dāng)那個(gè)職業(yè)經(jīng)紀(jì)人發(fā)現(xiàn)傳進(jìn)來(lái)需要監(jiān)控的文件描述符(下面用fd表示)有數(shù)據(jù)準(zhǔn)備好的,然后就一股腦的把所有fd傳回去灭红,完全不告訴你那個(gè)fd準(zhǔn)備好了侣滩,這樣我recvfrom又得循環(huán)所有fd,查看哪個(gè)有數(shù)據(jù)的变擒,再進(jìn)行讀寫(xiě)君珠。這樣的話不僅在復(fù)制這個(gè)fd的時(shí)候會(huì)消耗大量cpu,而且重復(fù)勞動(dòng)太多了娇斑。這就好像是大學(xué)時(shí)候的坑爹教授在期末的時(shí)候跟我們說(shuō):考試的內(nèi)容都在這本書(shū)里面策添,這本書(shū)就是重點(diǎn),咱絕對(duì)不超綱毫缆,你們放心唯竹。。苦丁。浸颓。(每次聽(tīng)完都有種想揍人的沖動(dòng))

第二:監(jiān)控的文件描述符數(shù)量有限,最大是1024個(gè)

3旺拉、poll

那么产上,我們聰明的程序員就想改進(jìn)下select,那么他們最先改進(jìn)的就是監(jiān)控的文件描述符的限制账阻,原來(lái)不是說(shuō)有1024限制嗎蒂秘,那么我現(xiàn)在就把他設(shè)計(jì)成沒(méi)有限制,這個(gè)時(shí)候就出現(xiàn)了poll淘太,poll的基本原理和select差不多姻僧,而且poll和select一樣有著第一個(gè)缺點(diǎn),就是fd的數(shù)組在復(fù)制進(jìn)內(nèi)核空間和用戶空間之間蒲牧,開(kāi)銷會(huì)隨著文件描述符的增大而線性增大撇贺。

但是缺點(diǎn)要一點(diǎn)一點(diǎn)改,程序猿想出了個(gè)終極版本冰抢,就是epoll松嘶,徹底改進(jìn)了原來(lái)那種低效的無(wú)差別輪詢,而且不限數(shù)量挎扰。

4翠订、epoll

epoll和上面兩種模型不同的方式在于

1、從用戶空間到內(nèi)核態(tài)遵倦,數(shù)據(jù)只拷貝一次:

2尽超、epoll采用基于事件的就緒通知方式,epoll會(huì)給當(dāng)前監(jiān)控的fd每人發(fā)一個(gè)回調(diào)函數(shù)梧躺,當(dāng)有事件發(fā)生的時(shí)候似谁,內(nèi)核會(huì)采用類似callback的回調(diào)機(jī)制(有點(diǎn)像事件中斷),將文件描述符號(hào)放在一個(gè)文件描述符表里面,然后每次檢測(cè)這個(gè)表是不是為空巩踏,如果不為空就通知recvfrom進(jìn)行讀寫(xiě)數(shù)據(jù)秃诵,為空就阻塞。具體過(guò)程如下:

epoll提供了三個(gè)函數(shù)塞琼,epoll_create,epoll_ctl和epoll_wait菠净,epoll_create是創(chuàng)建一個(gè)epoll句柄;epoll_ctl是注冊(cè)要監(jiān)聽(tīng)的事件類型屈梁;epoll_wait則是等待事件的產(chǎn)生

epoll_create 創(chuàng)建一個(gè)epoll對(duì)象嗤练,一般epollfd = epoll_create()

epoll_ctl (epoll_add/epoll_del的合體),往epoll對(duì)象中增加/刪除某一個(gè)流的某一個(gè)事件

比如

epoll_ctl(epollfd, EPOLL_CTL_ADD, socket, EPOLLIN);//注冊(cè)緩沖區(qū)非空事件在讶,即有數(shù)據(jù)流入

epoll_ctl(epollfd, EPOLL_CTL_DEL, socket, EPOLLOUT);//注冊(cè)緩沖區(qū)非滿事件煞抬,即流可以被寫(xiě)入

epoll_wait(epollfd,...)等待直到注冊(cè)的事件發(fā)生

(注:當(dāng)對(duì)一個(gè)非阻塞流的讀寫(xiě)發(fā)生緩沖區(qū)滿或緩沖區(qū)空,write/read會(huì)返回-1构哺,并設(shè)置errno=EAGAIN革答。而epoll只關(guān)心緩沖區(qū)非滿和緩沖區(qū)非空事件)。

總結(jié):

(1)select曙强,poll實(shí)現(xiàn)需要自己不斷輪詢所有fd集合残拐,直到設(shè)備就緒,期間可能要睡眠和喚醒多次交替碟嘴。而epoll其實(shí)也需要調(diào)用epoll_wait不斷輪詢就緒鏈表溪食,期間也可能多次睡眠和喚醒交替,但是它是設(shè)備就緒時(shí)娜扇,調(diào)用回調(diào)函數(shù)错沃,把就緒fd放入就緒鏈表中,并喚醒在epoll_wait中進(jìn)入睡眠的進(jìn)程雀瓢。雖然都要睡眠和交替枢析,但是select和poll在“醒著”的時(shí)候要遍歷整個(gè)fd集合,而epoll在“醒著”的時(shí)候只要判斷一下就緒鏈表是否為空就行了刃麸,這節(jié)省了大量的CPU時(shí)間醒叁。這就是回調(diào)機(jī)制帶來(lái)的性能提升。

(2)select泊业,poll每次調(diào)用都要把fd集合從用戶態(tài)往內(nèi)核態(tài)拷貝一次把沼,并且要把current往設(shè)備等待隊(duì)列中掛一次,而epoll只要一次拷貝吁伺,而且把current往等待隊(duì)列上掛也只掛一次(在epoll_wait的開(kāi)始智政,注意這里的等待隊(duì)列并不是設(shè)備等待隊(duì)列,只是一個(gè)epoll內(nèi)部定義的等待隊(duì)列)箱蝠。這也能節(jié)省不少的開(kāi)銷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市宦搬,隨后出現(xiàn)的幾起案子牙瓢,更是在濱河造成了極大的恐慌,老刑警劉巖间校,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矾克,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡憔足,警方通過(guò)查閱死者的電腦和手機(jī)胁附,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)滓彰,“玉大人控妻,你說(shuō)我怎么就攤上這事〗野螅” “怎么了弓候?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)他匪。 經(jīng)常有香客問(wèn)我菇存,道長(zhǎng),這世上最難降的妖魔是什么邦蜜? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任依鸥,我火速辦了婚禮,結(jié)果婚禮上悼沈,老公的妹妹穿的比我還像新娘贱迟。我一直安慰自己,他們只是感情好井辆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布关筒。 她就那樣靜靜地躺著,像睡著了一般杯缺。 火紅的嫁衣襯著肌膚如雪蒸播。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,590評(píng)論 1 305
  • 那天萍肆,我揣著相機(jī)與錄音袍榆,去河邊找鬼。 笑死塘揣,一個(gè)胖子當(dāng)著我的面吹牛包雀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亲铡,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼才写,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼葡兑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起赞草,我...
    開(kāi)封第一講書(shū)人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤讹堤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后厨疙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體洲守,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年沾凄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了梗醇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡撒蟀,死狀恐怖叙谨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情牙肝,我是刑警寧澤唉俗,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站配椭,受9級(jí)特大地震影響虫溜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜股缸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一衡楞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧敦姻,春花似錦瘾境、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至旺入,卻和暖如春兑凿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背茵瘾。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工礼华, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拗秘。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓圣絮,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親雕旨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扮匠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355