Select、Poll和Epoll的區(qū)別是什么,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
成都創(chuàng)新互聯(lián)公司公司2013年成立,先為未央等服務建站,未央等地企業(yè),進行企業(yè)商務咨詢服務。為未央企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務解決您的所有建站問題。
1 select
select本質(zhì)上是通過設置或檢查存放fd標志位的數(shù)據(jù)結(jié)構(gòu)進行下一步處理。
這帶來缺點:
單個進程可監(jiān)視的fd數(shù)量被限制,即能監(jiān)聽端口的數(shù)量有限
單個進程所能打開的最大連接數(shù)有FD_SETSIZE宏定義,其大小是32個整數(shù)的大小(在32位的機器上,大小就是3232,同理64位機器上FD_SETSIZE為3264),當然我們可以對進行修改,然后 重新編譯內(nèi)核,但是性能可能會受到影響,這需要進一步的測試
一般該數(shù)和系統(tǒng)內(nèi)存關(guān)系很大,具體數(shù)目可以cat /proc/sys/fs/file-max察看。32位機默認1024個,64位默認2048。

對socket是線性掃描,即輪詢,效率較低:
僅知道有I/O事件發(fā)生,卻不知是哪幾個流,只會無差異輪詢所有流,找出能讀數(shù)據(jù)或?qū)憯?shù)據(jù)的流進行操作。同時處理的流越多,無差別輪詢時間越長 - O(n)。
當socket較多時,每次select都要通過遍歷FD_SETSIZE個socket,不管是否活躍,這會浪費很多CPU時間。如果能給 socket 注冊某個回調(diào)函數(shù),當他們活躍時,自動完成相關(guān)操作,即可避免輪詢,這就是epoll與kqueue。
調(diào)用過程

缺點
內(nèi)核需要將消息傳遞到用戶空間,都需要內(nèi)核拷貝動作。需要維護一個用來存放大量fd的數(shù)據(jù)結(jié)構(gòu),使得用戶空間和內(nèi)核空間在傳遞該結(jié)構(gòu)時復制開銷大。
每次調(diào)用select,都需要把fd集合從用戶態(tài)拷貝到內(nèi)核態(tài),這個開銷在fd很多時會很大
同時每次調(diào)用select都需要在內(nèi)核遍歷傳遞進來的所有fd,這個開銷在fd很多時也很大
select支持的文件描述符數(shù)量太小了,默認是1024
2 poll
poll的實現(xiàn)和select非常相似,只是描述fd集合的方式不同,poll使用pollfd結(jié)構(gòu)而不是select的fd_set結(jié)構(gòu),其他的都差不多,管理多個描述符也是進行輪詢,根據(jù)描述符的狀態(tài)進行處理,但是poll沒有最大文件描述符數(shù)量的限制。poll和select同樣存在一個缺點就是,包含大量文件描述符的數(shù)組被整體復制于用戶態(tài)和內(nèi)核的地址空間之間,而不論這些文件描述符是否就緒,它的開銷隨著文件描述符數(shù)量的增加而線性增大。
它將用戶傳入的數(shù)組拷貝到內(nèi)核空間
然后查詢每個fd對應的設備狀態(tài):
如果設備就緒,在設備等待隊列中加入一項繼續(xù)遍歷
若遍歷完所有fd后,都沒發(fā)現(xiàn)就緒的設備
掛起當前進程,直到設備就緒或主動超時,被喚醒后它又再次遍歷fd。這個過程經(jīng)歷多次無意義的遍歷。
沒有最大連接數(shù)限制,因其基于鏈表存儲
缺點
大量fd數(shù)組被整體復制于用戶態(tài)和內(nèi)核地址空間間,而不管是否有意義
如果報告了fd后,沒有被處理,那么下次poll時會再次報告該fd
3 epoll
可理解為event poll,epoll會把哪個流發(fā)生哪種I/O事件通知我們。所以epoll是事件驅(qū)動(每個事件關(guān)聯(lián)fd)的,此時我們對這些流的操作都是有意義的。復雜度也降低到了O(1)。
3.1 觸發(fā)模式
EPOLLLT和EPOLLET兩種:
LT,默認的模式(水平觸發(fā))
只要該fd還有數(shù)據(jù)可讀,每次 epoll_wait 都會返回它的事件,提醒用戶程序去操作,
ET是“高速”模式(邊緣觸發(fā))

只會提示一次,直到下次再有數(shù)據(jù)流入之前都不會再提示,無論fd中是否還有數(shù)據(jù)可讀。所以在ET模式下,read一個fd的時候一定要把它的buffer讀完,即讀到read返回值小于請求值或遇到EAGAIN錯誤
epoll使用“事件”的就緒通知方式,通過epoll_ctl注冊fd,一旦該fd就緒,內(nèi)核就會采用類似回調(diào)機制激活該fd,epoll_wait便可收到通知。
3.2 優(yōu)點
沒有最大并發(fā)連接的限制,能打開的FD的上限遠大于1024(1G的內(nèi)存上能監(jiān)聽約10萬個端口)
效率提升,不是輪詢,不會隨著FD數(shù)目的增加效率下降。只有活躍可用的FD才會調(diào)用callback函數(shù)
即Epoll最大的優(yōu)點就在于它只關(guān)心“活躍”的連接,而跟連接總數(shù)無關(guān),因此在實際的網(wǎng)絡環(huán)境中,Epoll的效率就會遠遠高于select和poll
內(nèi)存拷貝,利用mmap()文件映射內(nèi)存加速與內(nèi)核空間的消息傳遞;即epoll使用mmap減少復制開銷。
epoll通過內(nèi)核和用戶空間共享一塊內(nèi)存來實現(xiàn)的
表面上看epoll的性能最好,但是在連接數(shù)少并且連接都十分活躍的情況下,select和poll的性能可能比epoll好,畢竟epoll的通知機制需要很多函數(shù)回調(diào)。
epoll跟select都能提供多路I/O復用的解決方案。在現(xiàn)在的Linux內(nèi)核里有都能夠支持,其中epoll是Linux所特有,而select則應該是POSIX所規(guī)定,一般操作系統(tǒng)均有實現(xiàn)。
4 總結(jié)
select,poll,epoll都是IO多路復用機制,即可以監(jiān)視多個描述符,一旦某個描述符就緒(讀或?qū)懢途w),能夠通知程序進行相應讀寫操作。
但select,poll,epoll本質(zhì)上都是同步I/O,因為他們都需要在讀寫事件就緒后自己負責進行讀寫,也就是說這個讀寫過程是阻塞的,而異步I/O則無需自己負責進行讀寫,異步I/O的實現(xiàn)會負責把數(shù)據(jù)從內(nèi)核拷貝到用戶空間。
關(guān)于Select、Poll和Epoll的區(qū)別是什么問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。
網(wǎng)站題目:Select、Poll和Epoll的區(qū)別是什么
本文URL:http://www.chinadenli.net/article16/geidgg.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設計、定制網(wǎng)站、微信公眾號、網(wǎng)站制作、網(wǎng)站維護、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)