select,epoll,poll比較

select,poll,epoll簡介 數組

select 數據結構

select本質上是經過設置或者檢查存放fd標誌位的數據結構來進行下一步處理。這樣所帶來的缺點是: socket

1 單個進程可監視的fd數量被限制 函數

2 須要維護一個用來存放大量fd的數據結構,這樣會使得用戶空間和內核空間在傳遞該結構時複製開銷大 性能

3 對socket進行掃描時是線性掃描 測試

poll spa

poll本質上和select沒有區別,它將用戶傳入的數組拷貝到內核空間,而後查詢每一個fd對應的設備狀態,若是設備就緒則在設備等待隊列中加入一項並繼續遍歷,若是遍歷完全部fd後沒有發現就緒設備,則掛起當前進程,直到設備就緒或者主動超時,被喚醒後它又要再次遍歷fd。這個過程經歷了屢次無謂的遍歷。 隊列

沒有最大鏈接數的限制,緣由是它是基於鏈表來存儲的,可是一樣有一個缺點: 進程

大量的fd的數組被總體複製於用戶態和內核地址空間之間,而無論這樣的複製是否是有意義。 事件

poll還有一個特色是「水平觸發」若是報告了fd後,沒有被處理,那麼下次poll時會再次報告該fd

epoll

epoll支持水平觸發和邊緣觸發,最大的特色在於邊緣觸發,它只告訴進程哪些fd剛剛變爲就需態,而且只會通知一次。

在前面說到的複製問題上,epoll使用mmap減小複製開銷。

還有一個特色是,epoll使用「事件」的就緒通知方式,經過epoll_ctl註冊fd,一旦該fd就緒,內核就會採用相似callback的回調機制來激活該fd,epoll_wait即可以收到通知

1 支持一個進程所能打開的最大鏈接數

select

單個進程所能打開的最大鏈接數有FD_SETSIZE宏定義,其大小是32個整數的大小(在32位的機器上,大小就是32*32,同理64位機器上FD_SETSIZE爲32*64),固然咱們能夠對進行修改,而後從新編譯內核,可是性能可能會受到影響,這須要進一步的測試。

poll

poll本質上和select沒有區別,可是它沒有最大鏈接數的限制,緣由是它是基於鏈表來存儲的

epoll

雖然鏈接數有上限,可是很大,1G內存的機器上能夠打開10萬左右的鏈接,2G內存的機器能夠打開20萬左右的鏈接

2 FD劇增後帶來的IO效率問題

select

由於每次調用時都會對鏈接進行線性遍歷,因此隨着FD的增長會形成遍歷速度慢的「線性降低性能問題」。

poll

同上

epoll

由於epoll內核中實現是根據每一個fd上的callback函數來實現的,只有活躍的socket纔會主動調用callback,因此在活躍 socket較少的狀況下,使用epoll沒有前面二者的線性降低的性能問題,可是全部socket都很活躍的狀況下,可能會有性能問題。

3 消息傳遞方式

select

內核須要將消息傳遞到用戶空間,都須要內核拷貝動做

poll

同上

epoll

epoll經過內核和用戶空間共享一塊內存來實現的。

綜上,在選擇select,poll,epoll時要根據具體的使用場合以及這三種方式的自身特色。表面上看epoll的性能最好,可是在鏈接數少而且鏈接都十分活躍的狀況下,select和poll的性能可能比epoll好,畢竟epoll的通知機制須要不少函數回調

相關文章
相關標籤/搜索