epoll與select的區別

2021-06-16 16:26:16 字數 1598 閱讀 7372

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 採用的是輪詢的方式當檢測的量太大時會造...