linux網絡編程poll與epoll區別

poll()函數:這個函數是某些Unix系統提供的用於執行與select()函數同等功能的函數,下面是這個函數的聲明:

#include <poll.h>

int poll(struct pollfd fds[], nfds_t nfds, int timeout);

參數說明:

fds:是一個struct pollfd結構類型的數組,用於存放需要檢測其狀態的Socket描述符;每當調用這個函數之後,系統不會清空這個數組,操作起來比較方便;特別是對於socket連接比較多的情況下,在一定程度上可以提高處理的效率;這一點與select()函數不同,調用select()函數之後,select()函數會清空它所檢測的socket描述符集合,導致每次調用select()之前都必須把socket描述符重新加入到待檢測的集合中;因此,select()函數適合於只檢測一個socket描述符的情況,而poll()函數適合於大量socket描述符的情況;

nfds:nfds_t類型的參數,用於標記數組fds中的結構體元素的總數量;

timeout:是poll函數調用阻塞的時間,單位:毫秒;

返回值的含義:

>0:數組fds中準備好讀、寫或出錯狀態的那些socket描述符的總數量;

==0:數組fds中沒有任何socket描述符準備好讀、寫,或出錯;此時poll超時,超時時間是timeout毫秒;換句話說,如果所檢測的socket描述符上沒有任何事件發生的話,那麼poll()函數會阻塞timeout所指定的毫秒時間長度之後返回,如果timeout==0,那麼poll() 函數立即返回而不阻塞,如果timeout==INFTIM,那麼poll() 函數會一直阻塞下去,直到所檢測的socket描述符上的感興趣的事件發生是才返回,如果感興趣的事件永遠不發生,那麼poll()就會永遠阻塞下去;

-1: poll函數調用失敗,同時會自動設置全局變量errno;

所以可以看出poll的效率要比select高

但是上面介紹的select函數和poll函數都存在一個非常致命的缺點,由於網絡延時,任一時間只有部分的socket是“活躍”的,但是select/poll每次調用都會線性掃描全部的集合,導致效率呈現線性下降。所以爲了解決這個問題epoll產生了

epoll不存在上面說的效率問題,它只會對“活躍”的socket進行操作---這是因爲在內核實現中epoll是根據每個fd上面的callback函數實現的。那麼,只有“活躍”的socket纔會主動的去調用 callback函數,其他idle狀態socket則不會,在這點上,epoll實現了一個“僞”AIO,因爲這時候推動力在os內核。在一些 benchmark中,如果所有的socket基本上都是活躍的---比如一個高速LAN環境,epoll並不比select/poll有什麼效率,相反,如果過多使用epoll_ctl,效率相比還有稍微的下降。但是一旦使用idle connections模擬WAN環境,epoll的效率就遠在select/poll之上了。

推薦閱讀:

Linux網絡編程之使用TCP傳輸文件 http://www.linuxidc.com/Linux/2013-06/85844.htm

Linux網絡編程之使用UDP傳輸文件 http://www.linuxidc.com/Linux/2013-06/85843.htm

Linux後臺網絡編程中select/poll/epoll的比較分析 http://www.linuxidc.com/Linux/2013-06/85455.htm

《UNIX網絡編程.卷2:進程間通信(第2版)》[PDF]  http://www.linuxidc.com/Linux/2013-01/77936.htm

Linux網絡編程的注意事項 http://www.linuxidc.com/Linux/2012-12/76087.htm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章