linux中epoll模型

epoll是linux內核爲處理大批量文件描述符而作了改進的poll,是linux下IO複用select/poll的增強版本。

一、epoll的主要接口是:

1、創建

(1)int epoll_create(int maxfds);

maxfds是支持的最大句柄數。該函數會返回一個新的epoll句柄,之後的函數調用都用這個句柄來操作。用完之後,記得用close()關閉這個創建出來的epoll句柄,否則可能導致系統fd被耗盡。

(2)int epoll_reate1(int flag);

上面創建的方法在linux 2.6.8之後,maxfds是被忽略的,所以建議採用epoll_create1(0)這種方法。另外epoll_create1(EPOLLCLOEXEC)表示生成的epoll fd具有“執行後關閉”的特性。

2、事件註冊

int epoll_ctl(int epfd,int op,int fd,struct epoll_event* event);

epoll的事件註冊函數,它不同於select/poll在監聽的時候告訴內核要監聽什麼事件,而是先註冊要監聽的事件類型。

(1)epfd爲(1)返回的epoll句柄

(2)op表示動作,用三個宏來表示:

EPOLL_CTL_ADD:註冊新的fd到epfd中

EPOLL_CTL_MOD:修改已註冊的fd的監聽事件

EPOLL_CTL_DEL:從epfd中刪除一個fd

(3)fd爲要監聽的fd

(4)event爲要監聽的事件,結構如下:

struct epoll_event

{

__uint32_t events;

epoll_data_t data;

};

events可以是一下宏的集合:

EPOLLIN :表示對應的文件描述符可以讀(包括對端SOCKET正常關閉);

EPOLLOUT:表示對應的文件描述符可以寫;

EPOLLPRI:表示對應的文件描述符有緊急的數據可讀(這裏應該表示有帶外數據到來);

EPOLLERR:表示對應的文件描述符發生錯誤;

EPOLLHUP:表示對應的文件描述符被掛斷;

EPOLLET: 將EPOLL設爲邊緣觸發(Edge Triggered)模式,這是相對於水平觸發(Level Triggered)來說的。

EPOLLONESHOT:只監聽一次事件,當監聽完這次事件之後,如果還需要繼續監聽這個socket的話,需要再次把這個socket加入到EPOLL隊列裏

3、等待事件發生

int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout);

等待事件發生,類似於select()調用。參數events用來從內核得到事件的集合,maxevents告訴內核這個events有多大,maxevents不能大於epoll_create時設置的size,參數timeout是超時時間(毫秒,0立即返回,-1將永久阻塞)。該函數返回需要處理的事件數目,如果返回0表示已超時。

二、epoll的兩種工作模式

epoll默認的工作模式是Level Triggered,通過epoll_ctl可以設置epoll的工作模式爲Edge Triggered。

LT(levet triggered)同時支持block和no-block socket。在該模式下,內核告訴你一個文件描述符是否就緒了,然後你可以對這個就緒的fd進行IO操作。如果你不作任何操作,內核還是會繼續通知你的,所以,這種模式編程出錯的可能性要小一點。傳統的select/poll都是這種模型的代表。

ET(edge triggered)是高速工作方式,只支持non-block socket。在這種模式下,當描述符從未就緒變爲就緒時,內核通過epoll告訴你。如果描述符沒有再次發生IO操作(導致它再次變成未就緒),內核不會發送更多的通知。例如:ET模式下epoll_wait返回,當前緩存中接收到了2KB的數據,調用read讀取1KB的數據。下次循環調用epoll_wai時將不會受到內核通知,將阻塞在這裏,直到發生IO操作(如又收到數據)。當調用read或者write返回EAGAIN時,才需要掛起。但我們一般在處理循環讀時,當read()返回的讀到的數據長度小於請求的數據長度時,就可以確定此時緩衝中已沒有數據了,也就可以認爲此事讀事件已處理完成。

三、epoll相對於select/poll的優勢

1、epoll通過epoll_ctl註冊監聽的事件,而不像select/poll在每次循環調用select/poll函數時,設置監聽事件,把fd集合從用戶態拷貝到內核態),這個開銷在fd很多時會很大。

2、select/poll在監聽事件發生後,需要遍歷所有fd,這個開銷在fd很多時也很大,而epoll_wait返回的就是需要處理的事件。

3、select支持的最大文件描述符個數默認爲1024,不適合處理大批量的文件描述符。而epoll就沒有限制。

4、在併發連接數較大而活動連接數較小時,epoll比poll效率更高;而如果所有連接基本都是活躍的,比如一個高速LAN環境,epoll並不比select/poll有什麼效率。

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