I/O基礎(chǔ)知識

一敦腔、Linux網(wǎng)絡(luò)I/O模型簡介

Linux的內(nèi)核將所有外部設(shè)備都看做一個(gè)文件來操作余蟹,對一個(gè)文件的讀寫操作會調(diào)用內(nèi)核提供的系統(tǒng)命令迎瞧,返回一個(gè)file descriptor(fd哮缺,文件描述符 )苟穆。而對一個(gè)socket的讀寫也會有相應(yīng)的描述符验辞,稱為socketfd(socket描述符)稿黄,描述符就是一個(gè)數(shù)字,它指向內(nèi)核中的一個(gè)結(jié)構(gòu)體(文件路徑跌造,數(shù)據(jù)區(qū)等一些屬性)杆怕。

根據(jù)UNIX網(wǎng)絡(luò)編程對I/O模型的分類,UNIX提供了5種I/O模型鼻听,分別如下:

  • 阻塞I/O模型
    最常用的I/O模型就是阻塞I/O模型财著,缺省情形下,所有文件操作都是阻塞的撑碴。我們以套接字接口為例來講解此模型撑教。在進(jìn)程空間中調(diào)用recvfrom,其系統(tǒng)調(diào)用直到數(shù)據(jù)包到達(dá)且被復(fù)制到應(yīng)用進(jìn)程的緩沖區(qū)中或者發(fā)生錯(cuò)誤時(shí)才返回醉拓,在此期間一直會等待伟姐,進(jìn)程在從調(diào)用recvfrom開始到它返回的整段時(shí)間內(nèi)都是被阻塞的,因此被稱為阻塞I/O模型亿卤。
阻塞I/O模型
  • 非阻塞I/O模型
    rcvfrom從應(yīng)用層到內(nèi)核的時(shí)候愤兵,如果該緩沖區(qū)沒有數(shù)據(jù)的話,就直接返回一個(gè)EWOULDBLOCK錯(cuò)誤排吴,一般都對非阻塞I/O模型進(jìn)行輪詢檢查這個(gè)狀態(tài)秆乳,看內(nèi)核是不是有數(shù)據(jù)到來。
非阻塞I/O模型
  • I/O復(fù)用模型
    Linux提供select/poll(I/O復(fù)用模型會用到select或者poll函數(shù)钻哩,這兩個(gè)函數(shù)也會使進(jìn)程阻塞屹堰,但是和阻塞I/O所不同的是,這兩個(gè)函數(shù)可以同時(shí)阻塞多個(gè)I/O操作街氢。而且可以同時(shí)對多個(gè)讀操作扯键,多個(gè)寫操作的I/O函數(shù)進(jìn)行檢測,直到有數(shù)據(jù)可讀或可寫時(shí)珊肃,才真正調(diào)用I/O操作函數(shù))荣刑,進(jìn)程通過將一個(gè)或多個(gè)fd傳遞給select或poll系統(tǒng)調(diào)用馅笙,阻塞在select操作上,這樣select/poll可以幫我們偵測多fd是否處于就緒狀態(tài)厉亏。select/poll是順序掃描fd是否就緒董习,而且支持的fd數(shù)量有限,因此它的使用受到了一些制約叶堆。Linux還提供了一個(gè)epoll系統(tǒng)調(diào)用阱飘,epoll使用基于事件驅(qū)動方式代替順序掃描,因此性能更高虱颗。當(dāng)有fd就緒時(shí)沥匈,立即回調(diào)函數(shù)rollback。
I/O復(fù)用模型
  • 信號驅(qū)動I/O模型
    首先開啟套接口信號驅(qū)動I/O功能忘渔,并通過系統(tǒng)調(diào)用sigaction執(zhí)行一個(gè)信號處理函數(shù)(此系統(tǒng)調(diào)用立即返回高帖,進(jìn)程繼續(xù)工作,它是非阻塞的)畦粮。當(dāng)數(shù)據(jù)準(zhǔn)備就緒時(shí)散址,就為該進(jìn)程生成一個(gè)SIGIO信號,通過信號回調(diào)通知應(yīng)用程序調(diào)用recvfrom來讀取數(shù)據(jù)宣赔,并通知主循環(huán)函數(shù)處理數(shù)據(jù)预麸。
信號驅(qū)動I/O模型
  • 異步I/O
    告知內(nèi)核啟動某個(gè)操作,并讓內(nèi)核在整個(gè)操作完成后(包括將數(shù)據(jù)從內(nèi)核復(fù)制到用戶自己的緩沖區(qū))通知我們儒将。這種模型與信號驅(qū)動模型的主要區(qū)別是:信號驅(qū)動I/O由內(nèi)核通知我們何時(shí)可以開始一個(gè)I/O操作吏祸;異步I/O模型由內(nèi)核通知我們I/O操作何時(shí)已經(jīng)完成
異步I/O

二钩蚊、I/O多路復(fù)用技術(shù)

在I/O編程過程中贡翘,當(dāng)需要同時(shí)處理多個(gè)客戶端接入請求時(shí),可以利用多線程或者I/O多路復(fù)用技術(shù)進(jìn)行處理砰逻。I/O多路復(fù)用技術(shù)通過把多個(gè)I/O的阻塞復(fù)用到同一個(gè)select的阻塞上鸣驱,從而使得系統(tǒng)在單線程的情況下可以同時(shí)處理多個(gè)客戶端請求。與傳統(tǒng)的多線程/多進(jìn)程模型比蝠咆,I/O多路復(fù)用的最大優(yōu)勢是系統(tǒng)開銷小踊东,系統(tǒng)不需要創(chuàng)建新的額外進(jìn)程或者線程,也不需要維護(hù)這些進(jìn)程和線程的運(yùn)行刚操,降底了系統(tǒng)的維護(hù)工作量闸翅,節(jié)省了系統(tǒng)資源,I/O多路復(fù)用的主要應(yīng)用場景如下:

  • 服務(wù)器需要同時(shí)處理多個(gè)處于監(jiān)聽狀態(tài)或者多個(gè)連接狀態(tài)的套接字赡茸。
  • 服務(wù)器需要同時(shí)處理多種網(wǎng)絡(luò)協(xié)議的套接字缎脾。

目前支持I/O多路復(fù)用的系統(tǒng)調(diào)用有 select祝闻,pselect占卧,poll遗菠,epoll,在Linux網(wǎng)絡(luò)編程過程中华蜒,很長一段時(shí)間都使用select做輪詢和網(wǎng)絡(luò)事件通知辙纬,然而select的一些固有缺陷導(dǎo)致了它的應(yīng)用受到了很大的限制,最終Linux不得不在新的內(nèi)核版本中尋找select的替代方案叭喜,最終選擇了epoll贺拣。epoll與select的原理比較類似,為了克服select的缺點(diǎn)捂蕴,epoll作了很多重大改進(jìn)譬涡,現(xiàn)總結(jié)如下:

  1. 支持一個(gè)進(jìn)程打開的socket描述符(FD)不受限制(僅受限于操作系統(tǒng)的最大文件句柄數(shù))。
    select最大的缺陷就是單個(gè)進(jìn)程所打開的FD是有一定限制的啥辨,它由FD_SETSIZE設(shè)置涡匀,默認(rèn)值是1024。對于那些需要支持上萬個(gè)TCP連接的大型服務(wù)器來說顯然太少了溉知≡纱瘢可以選擇修改這個(gè)宏,然后重新編譯內(nèi)核级乍,不過這會帶來網(wǎng)絡(luò)效率的下降舌劳。我們也可以通過選擇多進(jìn)程的方案(傳統(tǒng)的Apache方案)解決這個(gè)問題,不過雖然在Linux上創(chuàng)建進(jìn)程的代價(jià)比較小玫荣,但仍舊是不可忽視的甚淡,另外,進(jìn)程間的數(shù)據(jù)交換非常麻煩崇决,對于Java由于沒有共享內(nèi)存材诽,需要通過Socket通信或者其他方式進(jìn)行數(shù)據(jù)同步,這帶來了額外的性能損耗恒傻,增加了程序復(fù)雜度脸侥,所以也不是一種完美的解決方案。值得慶幸的是盈厘,epoll并沒有這個(gè)限制睁枕,它所支持的FD上限是操作系統(tǒng)的最大文件句柄數(shù),這個(gè)數(shù)字遠(yuǎn)遠(yuǎn)大于1024沸手。例如外遇,在1GB內(nèi)存的機(jī)器上大約是10萬個(gè)句柄左右,具體的值可以通過cat/proc/sys/fs/filemax察看契吉,通常情況下這個(gè)值跟系統(tǒng)的內(nèi)存關(guān)系比較大跳仿。

  2. I/O效率不會隨著FD數(shù)目的增加而線性下降。
    傳統(tǒng)的select/poll另一個(gè)致命弱點(diǎn)就是當(dāng)你擁有一個(gè)很大的socket集合捐晶,由于網(wǎng)絡(luò)延時(shí)或者鏈路空閑菲语,任一時(shí)刻只有少部分的socket是“活躍”的妄辩,但是select/poll每次調(diào)用都會線性掃描全部集合,導(dǎo)致效率呈現(xiàn)線性下降山上。epoll不存在這個(gè)問題眼耀,它只會對“活躍”的socket進(jìn)行操作-這是因?yàn)樵趦?nèi)核實(shí)現(xiàn)中epoll是根據(jù)每個(gè)fd上面的callback函數(shù)實(shí)現(xiàn)的,那么,只有“活躍”的socket才會主動的去調(diào)用callback函數(shù),其他idle狀態(tài)socket則不會晒奕。在這點(diǎn)上,epoll實(shí)現(xiàn)了一個(gè)偽AIO楞黄。針對epoll和select性能對比的benchmark測試表明:如果所有的socket都處于活躍態(tài)。例如一個(gè)高速LAN環(huán)境抡驼,epoll并不比select/poll效率高太多谅辣;相反,如果過多使用epoll_ctl婶恼,效率相比還有稍微的下降桑阶。但是一旦使用idle connections模擬WAN環(huán)境,epoll的效率就遠(yuǎn)在select/poll之上了勾邦。

  3. 使用mmap加速內(nèi)核與用戶空間的消息傳遞
    無論是select蚣录,poll還是epoll都需要內(nèi)核把FD消息通知給用戶空間,如何避免不必要的內(nèi)存復(fù)制就顯得非常重要眷篇,epoll是通過內(nèi)核和用戶空間mmap使用同一塊內(nèi)存實(shí)現(xiàn)萎河。

  4. epoll的API更加簡單
    用來克服select/poll缺點(diǎn)的方法不只有epoll,epoll只是一種Linux的實(shí)現(xiàn)方案蕉饼。在freeBSD下有kqueue虐杯,而dev/poll是最古老的Solaris的方案,使用難度依次遞增昧港。但epoll更加簡單擎椰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市创肥,隨后出現(xiàn)的幾起案子达舒,更是在濱河造成了極大的恐慌,老刑警劉巖叹侄,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巩搏,死亡現(xiàn)場離奇詭異,居然都是意外死亡趾代,警方通過查閱死者的電腦和手機(jī)贯底,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撒强,“玉大人禽捆,你說我怎么就攤上這事糯俗。” “怎么了睦擂?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長杖玲。 經(jīng)常有香客問我顿仇,道長,這世上最難降的妖魔是什么摆马? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任臼闻,我火速辦了婚禮,結(jié)果婚禮上囤采,老公的妹妹穿的比我還像新娘述呐。我一直安慰自己,他們只是感情好蕉毯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布乓搬。 她就那樣靜靜地躺著,像睡著了一般代虾。 火紅的嫁衣襯著肌膚如雪进肯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天棉磨,我揣著相機(jī)與錄音江掩,去河邊找鬼。 笑死乘瓤,一個(gè)胖子當(dāng)著我的面吹牛环形,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衙傀,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼抬吟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了统抬?” 一聲冷哼從身側(cè)響起拗军,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蓄喇,沒想到半個(gè)月后发侵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妆偏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年刃鳄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钱骂。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡叔锐,死狀恐怖挪鹏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情愉烙,我是刑警寧澤讨盒,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站步责,受9級特大地震影響返顺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蔓肯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一遂鹊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蔗包,春花似錦秉扑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至耻矮,卻和暖如春吨娜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背淘钟。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工宦赠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人米母。 一個(gè)月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓勾扭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親铁瞒。 傳聞我的和親對象是個(gè)殘疾皇子妙色,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354

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