1. 程式人生 > >select、poll、epoll之間的區別總結

select、poll、epoll之間的區別總結

select、poll、epoll都是IO多路複用的機制,先是監聽多個檔案描述符FD,一旦某個FD就緒,就可以進行相應的讀寫操作。但是select、poll、epoll本質都是同步I/O,他們都需要在讀寫事件就緒之後自己負責讀寫,即這個讀寫過程是阻塞的

1 select/poll

select缺點:

【1】每次呼叫select都需要把fd從使用者態拷貝到核心態,開銷比較大

【2】每次都需要在核心遍歷傳入的fd

【3】select支援檔案數量比較小,預設是1024

poll的實現和select非常相似,只是描述fd集合的方式不同,poll使用pollfd結構而不是select的fd_set結構,就不贅述了

2 epoll牛在哪裡?

select/poll只提供了一個函式,selct/poll函式,但是epoll一下子就提供了3個函式,真是人多力量大,難怪這麼強,如下3個函式:

epoll_create,epoll_ctl和epoll_wait,epoll_create是建立一個epoll句 柄;epoll_ctl是註冊要監聽的事件型別;epoll_wait則是等待事件的產生。

優點:

【1】每次註冊新事件到epoll控制代碼都會把所有的fd拷貝進來,而不是在epoll_wait中重複拷貝,這樣確保fd只會被拷貝一次

【2】epoll不是想select/poll那樣每次都把fd加入等待佇列中,epoll把每個fd指定一個回撥函式,當裝置就緒時,喚醒等待佇列的等待者就會呼叫其的回撥函式,這個回撥函式會把就緒的fd放入一個就緒連結串列。epoll_wait就是在這個就緒連結串列中檢視有沒有就緒fd

【3】epoll沒有fd數目限制

總結: (1)select,poll實現需要自己不斷輪詢所有fd集合,直到裝置就緒,期間可能要睡眠和喚醒多次交替。而epoll其實也需要呼叫 epoll_wait不斷輪詢就緒連結串列,期間也可能多次睡眠和喚醒交替,但是它是裝置就緒時,呼叫回撥函式,把就緒fd放入就緒連結串列中,並喚醒在 epoll_wait中進入睡眠的程序。雖然都要睡眠和交替,但是select和poll在“醒著”的時候要遍歷整個fd集合,而epoll在“醒著”的 時候只要判斷一下就緒連結串列是否為空就行了,這節省了大量的CPU時間。這就是回撥機制帶來的效能提升。 (2)select,poll每次呼叫都要把fd集合從使用者態往核心態拷貝一次,並且要把current往裝置等待佇列中掛一次,而epoll只要 一次拷貝,而且把current往等待佇列上掛也只掛一次(在epoll_wait的開始,注意這裡的等待佇列並不是裝置等待佇列,只是一個epoll內 部定義的等待佇列)。這也能節省不少的開銷。