【轉】IO模型及select械馆、poll、epoll和kqueue的區(qū)別

【轉】IO模型及select武通、poll霹崎、epoll和kqueue的區(qū)別

(一)首先,介紹幾種常見的I/O模型及其區(qū)別冶忱,如下:

blocking I/O

nonblocking I/O

I/O multiplexing (selectandpoll)

signal driven I/O (SIGIO)

asynchronous I/O (the POSIXaio_functions)—————異步IO模型最大的特點是 完成后發(fā)回通知尾菇。

阻塞與否,取決于實現(xiàn)IO交換的方式囚枪。

異步阻塞是基于select派诬,select函數(shù)本身的實現(xiàn)方式是阻塞的,而采用select函數(shù)有個好處就是它可以同時監(jiān)聽多個文件句柄.

異步非阻塞直接在完成后通知链沼,用戶進程只需要發(fā)起一個IO操作然后立即返回默赂,等IO操作真正的完成以后,應用程序會得到IO操作完成的通知括勺,此時用戶進程只需要對數(shù)據(jù)進行處理就好了缆八,不需要進行實際的IO讀寫操作谒臼,因為真正的IO讀取或者寫入操作已經由內核完成了。

1 blocking I/O

這個不用多解釋吧耀里,阻塞套接字蜈缤。下圖是它調用過程的圖示:

重點解釋下上圖,下面例子都會講到冯挎。首先application調用 recvfrom()轉入kernel底哥,注意kernel有2個過程,wait for data和copy data from kernel to user房官。直到最后copy complete后趾徽,recvfrom()才返回。此過程一直是阻塞的翰守。

2 nonblocking I/O:

與blocking I/O對立的孵奶,非阻塞套接字,調用過程圖如下:

可以看見蜡峰,如果直接操作它了袁,那就是個輪詢。湿颅。直到內核緩沖區(qū)有數(shù)據(jù)载绿。

3 I/O multiplexing (select and poll)

最常見的I/O復用模型,select油航。

select先阻塞崭庸,有活動套接字才返回。與blocking I/O相比谊囚,select會有兩次系統(tǒng)調用怕享,但是select能處理多個套接字。

4 signal driven I/O (SIGIO)

只有UNIX系統(tǒng)支持镰踏,感興趣的課查閱相關資料

I/O multiplexing (select and poll)相比函筋,它的優(yōu)勢是,免去了select的阻塞與輪詢余境,當有活躍套接字時驻呐,由注冊的handler處理灌诅。

5 asynchronous I/O (the POSIX aio_functions)

很少有*nix系統(tǒng)支持芳来,windows的IOCP則是此模型

完全異步的I/O復用機制,因為縱觀上面其它四種模型猜拾,至少都會在由kernel copy data to appliction時阻塞即舌。而該模型是當copy完成后才通知application,可見是純異步的挎袜。好像只有windows的完成端口是這個模型顽聂,效率也很出色肥惭。

6 下面是以上五種模型的比較

可以看出,越往后紊搪,阻塞越少蜜葱,理論上效率也是最優(yōu)。

=====================分割線==================================

5種模型的比較比較清晰了耀石,剩下的就是把select,epoll,iocp,kqueue按號入座那就OK了牵囤。

select和iocp分別對應第3種與第5種模型,那么epoll與kqueue呢滞伟?其實也于select屬于同一種模型揭鳞,只是更高級一些,可以看作有了第4種模型的某些特性梆奈,如callback機制野崇。

為什么epoll,kqueue比select高級?

答案是亩钟,他們無輪詢乓梨。因為他們用callback取代了。想想看清酥,當套接字比較多的時候督禽,每次select()都要通過遍歷FD_SETSIZE個Socket來完成調度,不管哪個Socket是活躍的,都遍歷一遍。這會浪費很多CPU時間总处。如果能給套接字注冊某個回調函數(shù)狈惫,當他們活躍時,自動完成相關操作鹦马,那就避免了輪詢胧谈,這正是epoll與kqueue做的。

windows or *nix (IOCP or kqueue/epoll)荸频?

誠然菱肖,Windows的IOCP非常出色,目前很少有支持asynchronous I/O的系統(tǒng)旭从,但是由于其系統(tǒng)本身的局限性稳强,大型服務器還是在UNIX下。而且正如上面所述和悦,kqueue/epoll 與 IOCP相比退疫,就是多了一層從內核copy數(shù)據(jù)到應用層的阻塞,從而不能算作asynchronous I/O類鸽素。但是褒繁,這層小小的阻塞無足輕重,kqueue與epoll已經做得很優(yōu)秀了馍忽。

提供一致的接口棒坏,IO Design Patterns

實際上燕差,不管是哪種模型,都可以抽象一層出來坝冕,提供一致的接口徒探,廣為人知的有ACE,Libevent(基于reactor模式)這些,他們都是跨平臺的喂窟,而且他們自動選擇最優(yōu)的I/O復用機制刹帕,用戶只需調用接口即可。說到這里又得說說2個設計模式谎替,ReactorandProactor偷溺。見:Reactor模式--VS--Proactor模式Libevent是Reactor模型钱贯,ACE提供Proactor模型挫掏。實際都是對各種I/O復用機制的封裝。

Java nio包是什么I/O機制秩命?

現(xiàn)在可以確定尉共,目前的java本質是select()模型,可以檢查/jre/bin/nio.dll得知弃锐。至于java服務器為什么效率還不錯袄友。。我也不得而知霹菊,可能是設計得比較好吧剧蚣。。-_-旋廷。

=====================分割線==================================

總結一些重點:

只有IOCP是asynchronous I/O鸠按,其他機制或多或少都會有一點阻塞。

select低效是因為每次它都需要輪詢饶碘。但低效也是相對的目尖,視情況而定,也可通過良好的設計改善

epoll, kqueue扎运、select是Reacor模式瑟曲,IOCP是Proactor模式。

java nio包是select模型豪治。洞拨。

(二)epoll 與select的區(qū)別

1. 使用多進程或者多線程,但是這種方法會造成程序的復雜鬼吵,而且對與進程與線程的創(chuàng)建維護也需要很多的開銷扣甲。(Apache服務器是用的子進程的方式,優(yōu)點可以隔離用戶) ?(同步阻塞IO)

2.一種較好的方式為I/O多路轉接(I/O multiplexing)(貌似也翻譯多路復用)齿椅,先構造一張有關描述符的列表(epoll中為隊列)琉挖,然后調用一個函數(shù),直到這些描述符中的一個準備好時才返回涣脚,返回時告訴進程哪些I/O就緒示辈。select和epoll這兩個機制都是多路I/O機制的解決方案,select為POSIX標準中的遣蚀,而epoll為Linux所特有的矾麻。

區(qū)別(epoll相對select優(yōu)點)主要有三:

1.select的句柄數(shù)目受限,在linux/posix_types.h頭文件有這樣的聲明:#define __FD_SETSIZE??? 1024? 表示select最多同時監(jiān)聽1024個fd芭梯。而epoll沒有险耀,它的限制是最大的打開文件句柄數(shù)目。

2.epoll的最大好處是不會隨著FD的數(shù)目增長而降低效率玖喘,在selec中采用輪詢處理甩牺,其中的數(shù)據(jù)結構類似一個數(shù)組的數(shù)據(jù)結構,而epoll是維護一個隊列累奈,直接看隊列是不是空就可以了贬派。epoll只會對"活躍"的socket進行操作---這是因為在內核實現(xiàn)中epoll是根據(jù)每個fd上面的callback函數(shù)實現(xiàn)的。那么澎媒,只有"活躍"的socket才會主動的去調用 callback函數(shù)(把這個句柄加入隊列)搞乏,其他idle狀態(tài)句柄則不會,在這點上戒努,epoll實現(xiàn)了一個"偽"AIO请敦。但是如果絕大部分的I/O都是“活躍的”,每個I/O端口使用率很高的話储玫,epoll效率不一定比select高(可能是要維護隊列復雜)冬三。

3.使用mmap加速內核與用戶空間的消息傳遞。無論是select,poll還是epoll都需要內核把FD消息通知給用戶空間缘缚,如何避免不必要的內存拷貝就很重要勾笆,在這點上,epoll是通過內核于用戶空間mmap同一塊內存實現(xiàn)的桥滨。

關于epoll工作模式ET窝爪,LT

epoll有兩種工作方式

ET:Edge Triggered,邊緣觸發(fā)齐媒。僅當狀態(tài)發(fā)生變化時才會通知蒲每,epoll_wait返回。換句話喻括,就是對于一個事件邀杏,只通知一次。且只支持非阻塞的socket。

LT:Level Triggered望蜡,電平觸發(fā)(默認工作方式)唤崭。類似select/poll,只要還有沒有處理的事件就會一直通知,以LT方式調用epoll接口的時候脖律,它就相當于一個速度比較快的poll.支持阻塞和不阻塞的socket谢肾。

三 Linux并發(fā)網絡編程模型

1 ?Apache 模型,簡稱 PPC?( Process Per Connection 小泉,):為每個連接分配一個進程芦疏。主機分配給每個連接的時間和空間上代價較大,并且隨著連接的增多微姊,大量進程間切換開銷也增長了酸茴。很難應對大量的客戶并發(fā)連接。

2 ?TPC?模型( Thread Per Connection ):每個連接一個線程兢交。和PCC類似薪捍。

3 ?select 模型:I/O多路復用技術。

.1 每個連接對應一個描述魁淳。select模型受限于?FD_SETSIZE即進程最大打開的描述符數(shù)linux2.6.35為1024,實際上linux每個進程所能打開描數(shù)字的個數(shù)僅受限于內存大小飘诗,然而在設計select的系統(tǒng)調用時,卻是參考FD_SETSIZE的值界逛±ジ澹可通過重新編譯內核更改此值,但不能根治此問題息拜,對于百萬級的用戶連接請求 ?即便增加相應 進程數(shù)溉潭, 仍顯得杯水車薪呀。

.2select每次都會掃描一個文件描述符的集合少欺,這個集合的大小是作為select第一個參數(shù)傳入的值喳瓣。但是每個進程所能打開文件描述符若是增加了 ,掃描的效率也將減小赞别。

.3內核到用戶空間畏陕,采用內存復制傳遞文件描述上發(fā)生的信息。

4 poll 模型:I/O多路復用技術仿滔。poll模型將不會受限于FD_SETSIZE惠毁,因為內核所掃描的文件 描述符集合的大小是由用戶指定的,即poll的第二個參數(shù)崎页。但仍有掃描效率和內存拷貝問題鞠绰。

5 pselect模型:I/O多路復用技術。同select飒焦。

6 epoll模型:

.1)無文件描述字大小限制僅與內存大小相關

.2)epoll返回時已經明確的知道哪個socket fd發(fā)生了什么事件蜈膨,不用像select那樣再一個個比對。

.3)內核到用戶空間采用共享內存方式,傳遞消息翁巍。

四 :FAQ

1驴一、單個epoll并不能解決所有問題,特別是你的每個操作都比較費時的時候曙咽,因為epoll是串行處理的蛔趴。?所以你有還是必要建立線程池來發(fā)揮更大的效能挑辆。

2例朱、如果fd被注冊到兩個epoll中時,如果有時間發(fā)生則兩個epoll都會觸發(fā)事件鱼蝉。

3洒嗤、如果注冊到epoll中的fd被關閉,則其會自動被清除出epoll監(jiān)聽列表魁亦。

4渔隶、如果多個事件同時觸發(fā)epoll,則多個事件會被聯(lián)合在一起返回洁奈。

5间唉、epoll_wait會一直監(jiān)聽epollhup事件發(fā)生,所以其不需要添加到events中利术。

6呈野、為了避免大數(shù)據(jù)量io時,et模式下只處理一個fd,其他fd被餓死的情況發(fā)生印叁。linux建議可以在fd聯(lián)系到的結構中增加ready位被冒,然后epoll_wait觸發(fā)事件之后僅將其置位為ready模式,然后在下邊輪詢ready fd列表轮蜕。

參考:

http://blog.csdn.net/ysu108/article/details/7570571

http://techbbs.zol.com.cn/1/8_2245.html

轉自:http://blog.csdn.net/wenbingoon/article/details/9004512

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末昨悼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子跃洛,更是在濱河造成了極大的恐慌率触,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汇竭,死亡現(xiàn)場離奇詭異葱蝗,居然都是意外死亡,警方通過查閱死者的電腦和手機韩玩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門垒玲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人找颓,你說我怎么就攤上這事合愈。” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵佛析,是天一觀的道長益老。 經常有香客問我,道長寸莫,這世上最難降的妖魔是什么捺萌? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮膘茎,結果婚禮上桃纯,老公的妹妹穿的比我還像新娘。我一直安慰自己披坏,他們只是感情好态坦,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著棒拂,像睡著了一般伞梯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上帚屉,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天谜诫,我揣著相機與錄音,去河邊找鬼攻旦。 笑死喻旷,一個胖子當著我的面吹牛,可吹牛的內容都是我干的敬特。 我是一名探鬼主播掰邢,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼伟阔!你這毒婦竟也來了辣之?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤皱炉,失蹤者是張志新(化名)和其女友劉穎怀估,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體合搅,經...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡多搀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了灾部。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片康铭。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赌髓,靈堂內的尸體忽然破棺而出从藤,到底是詐尸還是另有隱情催跪,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布夷野,位于F島的核電站懊蒸,受9級特大地震影響,放射性物質發(fā)生泄漏悯搔。R本人自食惡果不足惜骑丸,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望妒貌。 院中可真熱鬧通危,春花似錦、人聲如沸苏揣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽平匈。三九已至,卻和暖如春藏古,著一層夾襖步出監(jiān)牢的瞬間增炭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工拧晕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留隙姿,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓厂捞,卻偏偏與公主長得像输玷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子靡馁,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內容