epoll跟select都能提供多路i/o復用的解決方案。在現在的linux核心裡有都能夠支援,其中epoll是linux所特有,而select則應該是posix所規定,一般作業系統均有實現。
網上現在關於這兩者不同的介紹已經到處都是了。我這裡也不能多說出什麼東西,只是記錄下我看了實現**之後的一些總結。
兩者的使用場景一般是通過乙個入口能夠同時監控多路i/o。一般使用的介面,
epool就是
int epoll_wait(
int epfd, struct epoll_event *events,
int maxevents,
int timeout);
select為:
intselect
(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
通過上述兩個函式能夠將呼叫執行緒阻塞,執行緒變為可執行條件有兩種情況:
無任何事件發生,超時時間已過
在所控制的i/o有事件到來
epoll_wait函式中看不到相關的監控資訊,因為是通過epoll_ctl已經加入,而select之間在函式呼叫中由(
fd_set
*readfds
,fd_set
*writefds
, fd_set
*exceptfds)傳入。epoll_wait飯互結果通過events返回,而select的傳入引數也是傳出引數。兩者傳出引數均表示發生事件的對應i/o標識。
兩種方式的區別主要體現在以下幾個方面:
select所能控制的i/o數有限,這主要是因為fd_set資料結構是乙個有大小的,相當與乙個定長所陣列。
select每次都需要重新設定所要監控的fd_set(因為呼叫之後會改變其內容),這增加了程式開銷。
select的效能要比epoll差,具體原因會在後續內容中詳細說明。
嗯,說道這個為什麼select要差,那就要從這個select api說起了。這個傳進去乙個陣列,內部實現也不知道那個有哪個沒有,所以要遍歷一遍。假設說我只監控乙個檔案描述符,但是他是1000。那麼select需要遍歷前999個之後再來poll這個1000的檔案描述符,而epoll則不需要,因為在之前epoll_ctl的呼叫過程中,已經維護了乙個佇列,所以直接等待事件到來就可以了。
linux中select此段相關**為:
/* 遍歷所有傳入的fd_set */
for(i = 0; i < n;
++rinp,
++routp,
++rexp)
/* 後續進行一些相關操作 */}
而epoll則無需進行此類操作,直接檢測內部維護的乙個就緒佇列,如果佇列有內容,說明有i/o就緒,那麼直接賦值返回內容,成功返回,如果沒有成功,那麼睡眠,等待就緒佇列非空。
通過這個兩者的比較,其實兩者的差距啊,大部分是因為這個api設計所決定的,select就設計成這樣乙個api,內部再怎麼優化也只能是這麼個爛樣子,而epoll這樣維護與等待分離,靈活多變,最後也就帶來了相對的高效能,以及可擴充套件性。
以後的**生涯中,還是先要設計好api,然後才能寫出好**……
(**:
Select和epoll的區別
當乙個節點和多個節點建立連線時,如何高效的處理多個連線的資料,下面具體分析兩者的區別。1.select函式 函式原型 int select int nfds,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout ...
Select和epoll的區別
當乙個節點和多個節點建立連線時,如何高效的處理多個連線的資料,下面具體分析兩者的區別。1.select函式 函式原型 int select int nfds,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout ...
epoll和select的區別
做以簡單區分為面試作答提供一些幫助 select 和 epoll都為一種網路i o模型,都是採用了檢測了控制代碼集合中的資料,來實現多路復用。select檔案控制代碼檢測數有限,核心中 fd setsize定義為2048超出範圍將無法檢測,在掃瞄上select 採用的是輪詢的方式當檢測的量太大時會造...