epoll程式設計框架

2021-07-22 04:50:59 字數 2733 閱讀 2704

epoll是linux核心中的一種可擴充套件io事件處理機制,最早在 linux 2.5.44核心中引入,可被用於代替posix select 和 poll 系統呼叫,並且在具有大量應用程式請求時能夠獲得較好的效能( 此時被監視的檔案描述符數目非常大,與舊的 select 和 poll 系統呼叫完成操作所需 o(n) 不同, epoll能在o(1)時間內完成操作,所以效能相當高),epoll 與 freebsd的kqueue類似,都向使用者空間提供了自己的檔案描述符來進行操作。

int epoll_create(int size);
建立乙個epoll的控制代碼,size用來告訴核心需要監聽的數目一共有多大。當建立好epoll控制代碼後,它就是會占用乙個fd值,在linux下如果檢視/proc/程序id/fd/,是能夠看到這個fd的,所以在使用完epoll後,必須呼叫close() 關閉,否則可能導致fd被耗盡。

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epoll的事件註冊函式,第乙個引數是 epoll_create() 的返回值,第二個引數表示動作,使用如下三個巨集來表示:

epoll_ctl_add    //

註冊新的fd到epfd中;

epoll_ctl_mod //

修改已經註冊的fd的監聽事件;

epoll_ctl_del //

從epfd中刪除乙個fd;

第三個引數是需要監聽的fd,第四個引數是告訴核心需要監聽什麼事,struct epoll_event 結構如下:

typedef union epoll_data

epoll_data_t;struct epoll_event ;

events 可以是以下幾個巨集的集合:

epollin //

表示對應的檔案描述符可以讀(包括對端socket正常關閉);

epollout//

表示對應的檔案描述符可以寫;

epollpri//

表示對應的檔案描述符有緊急的資料可讀(這裡應該表示有帶外資料到來);

epollerr//

表示對應的檔案描述符發生錯誤;

epollhup    //

表示對應的檔案描述符被結束通話;

epollet//

將epoll設為邊緣觸發(edge triggered)模式,這是相對於水平觸發(level triggered)來說的。

epolloneshot//

只監聽一次事件,當監聽完這次事件之後,如果還需要繼續監聽這個socket的話,需要再次把這個socket加入到epoll佇列裡。

當對方關閉連線(fin), epollerr,都可以認為是一種epollin事件,在read的時候分別有0,-1兩個返回值。

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
引數events用來從核心得到事件的集合,maxevents 告之核心這個events有多大,這個 maxevents 的值不能大於建立 epoll_create() 時的size,引數 timeout 是超時時間(毫秒,0會立即返回,-1將不確定,也有說法說是永久阻塞)。該函式返回需要處理的事件數目,如返回0表示已超時。

epoll事件有兩種模型level triggered (lt)edge triggered (et):

lt(level triggered,水平觸發模式)是預設的工作方式,並且同時支援 block 和 non-block socket。在這種做法中,核心告訴你乙個檔案描述符是否就緒了,然後你可以對這個就緒的fd進行io操作。如果你不作任何操作,核心還是會繼續通知你的,所以,這種模式程式設計出錯誤可能性要小一點。

et(edge-triggered,邊緣觸發模式)是高速工作方式,只支援no-block socket。在這種模式下,當描述符從未就緒變為就緒時,核心通過epoll告訴你。然後它會假設你知道檔案描述符已經就緒,並且不會再為那個檔案描述符傳送更多的就緒通知,等到下次有新的資料進來的時候才會再次出發就緒事件。

epoll程式設計例子:

把所有其他相關的**都略去,只留下epoll程式設計相關的框架**。其實這個都差不多

int main(int argc, char* argv)

{ //宣告epoll_event結構體的變數,ev用於註冊事件,陣列用於回傳要處理的事件

struct epoll_event ev,events[20];

//生成用於處理accept的epoll專用的檔案描述符

epfd=epoll_create(256);

//設定與要處理的事件相關的檔案描述符

ev.data.fd=listenfd;

//設定要處理的事件型別

ev.events=epollin|epollet;

//註冊epoll事件

epoll_ctl(epfd,epoll_ctl_add,listenfd,&ev);

for ( ; ; ) {

//等待epoll事件的發生

nfds=epoll_wait(epfd,events,20,500);

//處理所發生的所有事件

for(i=0;i

epoll程式設計

本章節是用基本的linux基本函式加上epoll呼叫編寫乙個完整的伺服器和客戶端例子,可在linux上執行,客戶端和服務端的功能如下 客戶端從標準輸入讀入一行,傳送到服務端 服務端從網路讀取一行,然後輸出到客戶端 客戶端收到服務端的響應,輸出這一行到標準輸出 如下 1 include2 includ...

linux網路程式設計之 epoll

include include include include include include include include include include using namespace std define maxline 5 define open max 100 define listen...

python 網路程式設計 epoll的大坑

eopll 例項預設監聽 select.epollhup 一般只需要監聽select.epollin事件就行了 在另一方關閉連線時會傳送乙個空串,select.epollin 會捕捉這個空串事件,如果不對它處理的話這個事件會一直響應,需要手動關閉 connection.close 一般將所有連線的描...