首頁 > 軟體

epol學習筆記

2020-06-16 17:44:12

epoll的相關系統呼叫

epoll_create()

epoll_ctl()

epoll_wait()

int epoll_create(int size);

建立一個epoll的控制代碼。

  1. 自從linux2.6.8之後,size引數是被忽略的。
  2. 建立epoll控制代碼後,它就是會佔用一個fd值,在使用完epoll後,必須呼叫close()關閉。

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

epoll的事件註冊函數。

  1. 第一個引數是epoll_create()的返回值。

  2. 第二個參數列示動作,用三個宏來表示:

    EPOLL_CTL_ADD:註冊新的fd到epfd中;

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

    EPOLL_CTL_DEL:從epfd中刪除一個fd。

  3. 第三個引數是需要監聽的fd。

  4. 第四個引數是告訴核心需要監聽什麼事。

struct epoll_event結構如下:

typedef union epoll_data

{//儲存觸發事件的某個檔案描述符相關的資料

    void *ptr;

    int fd;

    __uint32_t u32;

    __uint64_t u64;

} epoll_data_t;

 

struct epoll_event

{

__uint32_t events;/* Epoll events */

epoll_data_t data;/* User data variable */

};

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

  1. EPOLLIN:表示對應的檔案描述符可以讀(包括對端SOCKET正常關閉);
  2. EPOLLOUT:表示對應的檔案描述符可以寫;
  3. EPOLLPRI:表示對應的檔案描述符有緊急的資料可讀(這裡應該表示有帶外資料到來);
  4. EPOLLERR:表示對應的檔案描述符發生錯誤;
  5. EPOLLHUP:表示對應的檔案描述符被結束通話;
  6. EPOLLET:將EPOLL設為邊緣觸發(Edge Triggered)模式,這是相對於水平觸發(Level Triggered)來說的。
  7. EPOLLONESHOT:只監聽一次事件,當監聽完這次事件之後,如果還需要繼續監聽這個socket的話,需要再次把這個socket加入到EPOLL佇列裡。

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

收集在epoll監控的事件中已經發生的事件。

  1. 引數events是分配好的epoll_event結構體陣列,epoll將會把發生的事件賦值到events陣列中(events不可以是空指標,核心只負責把資料複製到這個events陣列中,不會去幫助我們在使用者態中分配記憶體)。
  2. maxevents告之核心這個events有多大,這個maxevents的值不能大於建立epoll_create()時的size。(自從linux2.6.8之後,size引數是被忽略的。)maxevents值使用cat /proc/sys/fs/file-max命令查詢,與記憶體的大小有關。
  3. 最後一個timeout是epoll_wait的超時,為0的時候表示馬上返回,為-1的時候表示一直等下去,直到有事件發生,為任意正整數的時候表示等這麼長的時間,如果一直沒有事件,則返回。一般如果網路主迴圈是單獨的執行緒的話,可以用-1來等,這樣可以保證一些效率,如果是和主邏輯在同一個執行緒的話,則可以用0來保證主迴圈的效率。
  4. 如果函數呼叫成功,返回對應I/O上已準備好的檔案描述符數目,如返回0表示已超時。

Edge Triggered 工作模式

  1. epoll工作在ET模式的時候,必須使用非阻塞套介面,以避免由於一個檔案控制代碼的阻塞讀/阻塞寫操作把處理多個檔案描述符的任務餓死。
  2. 最好以下面的方式呼叫ET模式的epoll介面,在後面會介紹避免可能的缺陷。

@ 基於非阻塞檔案控制代碼

@ 只有當read()或者write()返回EAGAIN時才需要掛起,等待。

但這並不是說每次read()時都需要迴圈讀,直到讀到產生一個EAGAIN才認為此次事件處理完成,當read()返回的讀到的資料長度小於請求的資料長度時,就可以確定此時緩衝中已沒有資料了,也就可以認為此事讀事件已處理完成。

本文永久更新連結地址http://www.linuxidc.com/Linux/2016-04/129815.htm


IT145.com E-mail:sddin#qq.com