Linux企業級開發技術(2)——epoll企業級開發之epoll介面

尹成發表於2014-09-23

 

epoll的介面非常簡單,總共只有三個函式:

 

1、int epoll_create(intsize);

 

生成一個 Epoll 專用的檔案描述符,size用來告訴核心這個監聽的數目一共有多大。這個引數不同於select()中的第一個引數,給出最大監聽的fd+1的值。需要注意的是,當建立好epoll控制程式碼後,它就是會佔用一個fd值,在linux下如果檢視/proc/程式id/fd/,是能夠看到這個fd的,所以在使用完epoll後,必須呼叫close()關閉,否則可能導致fd被耗盡。

其實是申請一個核心空間,用來存放你想關注的 socket fd 上是否發生以及發生了什麼事件。 size 就是你在這個 Epoll fd 上能關注的最大 socket fd 數,大小自定,只要記憶體足夠。

 

2、int epoll_ctl(intepfd, int op, int fd, struct epoll_event *event);

epoll的事件註冊函式,它不同與select()是在監聽事件時告訴核心要監聽什麼型別的事件,而是在這裡先註冊要監聽的事件型別。它用來控制某個epoll 檔案描述符上的事件:註冊、修改、刪除。其中引數 epfd 是 epoll_create() 建立 Epoll 專用的檔案描述符。相當於 select 模型中的 FD_SET 和 FD_CLR 巨集。

 

第一個引數是epoll_create()的返回值,

第二個參數列示動作,用三個巨集來表示:

EPOLL_CTL_ADD:註冊新的fd到epfd中;

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

EPOLL_CTL_DEL:從epfd中刪除一個fd;

第三個引數是需要監聽的fd,

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

struct epoll_event {
 __uint32_t events;  /* Epollevents */
 epoll_data_t data;  /* User datavariable */
};


 

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

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

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

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

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

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

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

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

 

3、int epoll_wait(intepfd, struct epoll_event * events, int maxevents, int timeout);

 

等待I/O事件的產生,類似於select()呼叫。

引數說明:

epfd: 由 epoll_create() 生成的 Epoll 專用的檔案描述符;

epoll_event: 用於回傳代處理事件的陣列;

maxevents: 每次能處理的事件數;

timeout: 等待 I/O 事件發生的超時值;

返回發生事件數。

 

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

 

4、其他epoll_XXX() 系統呼叫

在RHEL6的核心(主要基於2.6.32)裡,還有兩個與epoll有關的系統呼叫:

epoll_pwait(),epoll_create1()。這些只是上面三個系統呼叫的包裝而已。pwait是做了與程式訊號有關的工作,create1則是用來填補遺漏功能的。

相關文章