在linux的網路程式設計中,很長的時間都在使用select來做事件觸發。
在linux新的核心中,有了一種替換它的機制,就是epoll。
相比於select,epoll最大的好處在於它不會隨著監聽fd數目的增長而降低效率。
因為在核心中的select實現中,它是採用輪詢來處理的,輪詢的fd數目越多,自然耗時越多。
並且,linux/posix_types.h標頭檔案有這樣的宣告:
#define__fd_setsize 1024
表示select最多同時監聽1024個fd,當然,
可以通過修改標頭檔案再重編譯核心來擴大這個數目,但這似乎並不治本。
資料型別和巨集
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佇列裡。
api:
//標頭檔案
#include
1.epoll_create
【功能】建立epoll控制代碼
【原型】int epoll_create(int size)
【引數】1.size 用來告訴核心這個監聽的數目一共有多大
【返回值】epoll專用的檔案描述符
在使用完epoll後,必須呼叫close()關閉,否則可能導致fd被耗盡。
**2.epoll_ctl **
【功能】epoll的事件註冊函式,將被監聽的描述符新增到epoll控制代碼/從epool控制代碼中刪除描述符/對監聽事件進行修改。
【原型】int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
【引數】
1.epfd 由 epoll_create 生成的epoll專用的檔案描述符;
2.op 要進行的操作:例如註冊事件,可能的取值
epoll_ctl_add 註冊;epoll_ctl_mod 修 改;
epoll_ctl_del 刪除
3.fd 關聯的檔案描述符;
4.event 指向與fd關聯的epoll_event的指標;
【返回值】成功返回0,失敗返回-1
【描述】
epoll的事件註冊函式,它不同與select()是在監聽事件時告訴核心要監聽什麼型別的事件,而是在這裡先註冊要監聽的事件型別。
3.epoll_wait第乙個引數是epoll_create()的返回值,
第二個引數表示動作,用三個巨集來表示:
epoll_ctl_add:註冊新的fd到epfd中;
epoll_ctl_mod:修改已經註冊的fd的監聽事件;
epoll_ctl_del:從epfd中刪除乙個fd;
第三個引數是需要監聽的fd
第四個引數是與fd關聯的epoll_event物件,需指定fd和events
【功能】建立epoll控制代碼
【原型】int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
【引數】1.epfd 由 epoll_create 生成的epoll專用的檔案描述符;
2.events 監聽的事件集合
3.maxevents 表示每次能處理的最大事件數,必須大於零。
4.timeout 呼叫等待超時毫秒的最大時間。指定超時為-1將使epoll_wait()在指定時無限期等待
在將超時指定為零時,即使沒有可用的事件,epoll_wait()也會立即返回
【返回值】成功,返回為請求的i/o準備好的檔案描述符的數量,
如果在請求的超時毫秒期間沒有準備好檔案描述符,則返回0。
錯誤,epoll_wait()返回-1,並相應地設定errno。
epoll觸發事件的分析
我們知道,可以將套接字放入到epoll中監聽,當套接字上有事件發生時,epoll就會通知我們。epoll機制可以監聽套接字上的以下6種事件 那麼,什麼情況下會在套接字上觸發以上6種事件呢?當我們監聽套接字上的epollin epollrdhup事件時,總結如下 綜上,可能出現的事件組合為 1.epo...
epoll邊緣觸發 Epoll筆記
下圖為epoll的流程圖 epoll一共兩種模式,水平觸發 lt 和邊緣觸發 et 主要的區別在於對讀,寫資料的處理 lt初始化 epoll ctrl connect socket,epollin,add lt讀 void lt handle read if n 0 errno eagain lt寫...
epoll 水平觸發 邊緣觸發
水平觸發 只要緩衝區還有資料,核心就還會通知使用者。使用者如果第一次讀取資料沒讀完,即使沒有任何新的操作觸發,還是可以繼續通過epoll wait來獲取事件 邊緣觸發 只有當新事件觸發的時候,才能通過epoll wait來獲取資料,如果第一次讀取資料沒讀完,就只能等待下一次事件觸發來獲取餘下的資料。...