再谈select, iocp, epoll,kqueue及各种I/O复用机制 - Shallway - 博客频道 - CSDN.NET
生活随笔
收集整理的這篇文章主要介紹了
再谈select, iocp, epoll,kqueue及各种I/O复用机制 - Shallway - 博客频道 - CSDN.NET
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
再談select, iocp, epoll,kqueue及各種I/O復(fù)用機(jī)制 - Shallway - 博客頻道 - CSDN.NET
再談select, iocp, epoll,kqueue及各種I/O復(fù)用機(jī)制
? 分類: Network Linux 2010-01-28 14:33 11064人閱讀 評(píng)論(15) 收藏 舉報(bào)
asynchronouswindowsapplicationcallbacksignaljava
上篇文章太過(guò)幼稚,一派胡言,希望沒(méi)有誤導(dǎo)大家。。我也是菜鳥(niǎo),學(xué)習(xí)本身就是一個(gè)不斷追求真理的過(guò)程,希望能諒解:)首先感謝kasicass GG指出錯(cuò)誤(已經(jīng)指導(dǎo)我很多次了,非常感謝~~),然后我又查閱了一些資料,再次整理,more seriously and detailedly~
首先,介紹幾種常見(jiàn)的I/O模型及其區(qū)別,如下:
??? blocking I/O
??? nonblocking I/O
??? I/O multiplexing (select and poll)
??? signal driven I/O (SIGIO)
??? asynchronous I/O (the POSIX aio_functions)
blocking I/O
這個(gè)不用多解釋吧,阻塞套接字。下圖是它調(diào)用過(guò)程的圖示:
重點(diǎn)解釋下上圖,下面例子都會(huì)講到。首先application調(diào)用 recvfrom()轉(zhuǎn)入kernel,注意kernel有2個(gè)過(guò)程,wait for data和copy data from kernel to user。直到最后copy complete后,recvfrom()才返回。此過(guò)程一直是阻塞的。
nonblocking I/O:
與blocking I/O對(duì)立的,非阻塞套接字,調(diào)用過(guò)程圖如下:
可以看見(jiàn),如果直接操作它,那就是個(gè)輪詢。。直到內(nèi)核緩沖區(qū)有數(shù)據(jù)。
I/O multiplexing (select and poll)
最常見(jiàn)的I/O復(fù)用模型,select。
select先阻塞,有活動(dòng)套接字才返回。與blocking I/O相比,select會(huì)有兩次系統(tǒng)調(diào)用,但是select能處理多個(gè)套接字。
signal driven I/O (SIGIO)
只有UNIX系統(tǒng)支持,感興趣的課查閱相關(guān)資料
與I/O multiplexing (select and poll)相比,它的優(yōu)勢(shì)是,免去了select的阻塞與輪詢,當(dāng)有活躍套接字時(shí),由注冊(cè)的handler處理。
asynchronous I/O (the POSIX aio_functions)
很少有*nix系統(tǒng)支持,windows的IOCP則是此模型
完全異步的I/O復(fù)用機(jī)制,因?yàn)榭v觀上面其它四種模型,至少都會(huì)在由kernel copy data to appliction時(shí)阻塞。而該模型是當(dāng)copy完成后才通知application,可見(jiàn)是純異步的。好像只有windows的完成端口是這個(gè)模型,效率也很出色。
下面是以上五種模型的比較
可以看出,越往后,阻塞越少,理論上效率也是最優(yōu)。
=====================分割線==================================
5種模型的比較比較清晰了,剩下的就是把select,epoll,iocp,kqueue按號(hào)入座那就OK了。
select和iocp分別對(duì)應(yīng)第3種與第5種模型,那么epoll與kqueue呢?其實(shí)也于select屬于同一種模型,只是更高級(jí)一些,可以看作有了第4種模型的某些特性,如callback機(jī)制。
那么,為什么epoll,kqueue比select高級(jí)?
答案是,他們無(wú)輪詢。因?yàn)樗麄冇胏allback取代了。想想看,當(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做的。
windows or *nix (IOCP or kqueue/epoll)?
誠(chéng)然,Windows的IOCP非常出色,目前很少有支持asynchronous I/O的系統(tǒng),但是由于其系統(tǒng)本身的局限性,大型服務(wù)器還是在UNIX下。而且正如上面所述,kqueue/epoll 與 IOCP相比,就是多了一層從內(nèi)核copy數(shù)據(jù)到應(yīng)用層的阻塞,從而不能算作asynchronous I/O類。但是,這層小小的阻塞無(wú)足輕重,kqueue與epoll已經(jīng)做得很優(yōu)秀了。
提供一致的接口,IO Design Patterns
實(shí)際上,不管是哪種模型,都可以抽象一層出來(lái),提供一致的接口,廣為人知的有ACE,Libevent這些,他們都是跨平臺(tái)的,而且他們自動(dòng)選擇最優(yōu)的I/O復(fù)用機(jī)制,用戶只需調(diào)用接口即可。說(shuō)到這里又得說(shuō)說(shuō)2個(gè)設(shè)計(jì)模式,Reactor and Proactor。有一篇經(jīng)典文章http://www.artima.com/articles/io_design_patterns.html值得閱讀,Libevent是Reactor模型,ACE提供Proactor模型。實(shí)際都是對(duì)各種I/O復(fù)用機(jī)制的封裝。
Java nio包是什么I/O機(jī)制?
我曾天真的認(rèn)為java nio封裝的是IOCP。。現(xiàn)在可以確定,目前的java本質(zhì)是select()模型,可以檢查/jre/bin/nio.dll得知。至于java服務(wù)器為什么效率還不錯(cuò)。。我也不得而知,可能是設(shè)計(jì)得比較好吧。。-_-。
=====================分割線==================================
總結(jié)一些重點(diǎn):
??? 只有IOCP是asynchronous I/O,其他機(jī)制或多或少都會(huì)有一點(diǎn)阻塞。
??? select低效是因?yàn)槊看嗡夹枰喸儭5托б彩窍鄬?duì)的,視情況而定,也可通過(guò)良好的設(shè)計(jì)改善
??? epoll, kqueue是Reacor模式,IOCP是Proactor模式。
??? java nio包是select模型。。
OVER,寫得很累,轉(zhuǎn)載請(qǐng)注明出處,謝謝!
分享到:
上一篇:不發(fā)泄不足以平民憤。
下一篇:賞心悅目的宏代碼
查看評(píng)論
14樓 honggengwei 2012-04-30 21:19發(fā)表 [回復(fù)][引用] [舉報(bào)]
總結(jié)
以上是生活随笔為你收集整理的再谈select, iocp, epoll,kqueue及各种I/O复用机制 - Shallway - 博客频道 - CSDN.NET的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。