轉載: https://blog.csdn.net/qq_19923217/article/details/81943705linux
版權聲明:遵循 CC 4.0 BY-SA 版權協議編程
一. 概述
epoll 是 Linux 內核爲處理大批量文件描述符而做了改進的 poll,是 Linux 下多路複用 IO接口 select/poll 的加強版本數組
在 linux 的網絡編程中,很長時間都在使用 select 來作事件觸發。在 2.6 內核中,有一種替換它的機制,就是 epoll。網絡
select 與 epoll 區別概述
(1) 函數使用上:epoll 使用一組函數來完成任務,而不是單個函數併發
(2) 效率:select 使用輪詢來處理,隨着監聽 fd 數目的增長而下降效率。而 epoll 把用戶關心的文件描述符事件放在內核裏的一個事件表中,只須要一個額外的文件描述符來標識內核中的這個事件表便可。socket
二. epoll 接口
epoll 事件觸發併發處理操做過程總共須要三個接口,下面詳細說明這三個接口的使用。函數
頭文件
#include <sys/epoll.h>
1
1 int epoll_create(int size);
前面說到 epoll 使用內核事件表來實現 I/O 複用,因此須要一個額外的文件描述符來標識使用的內核事件表。ui
epoll_create 函數就是用來獲取內核事件表的特殊文件描述符,該函數返回的文件描述符將用做其餘 epoll 系統調用的第一個參數,以指定要訪問的內核事件表。.net
2 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epoll 的事件註冊函數,用來操做內核事件表。它不一樣與 select() 是在監聽事件時告訴內核要監聽什麼類型的事件,而是在這裏先註冊要監聽的事件類型。指針
參數含義:
1. epfd: 要操做的內核事件表的文件描述符,即 epoll_create 的返回值
2. op:指定操做類型,操做類型有三種:
-> EPOLL_CTL_ADD:往內核事件表中註冊指定fd 相關的事件
-> EPOLL_CTL_MOD:修改指定 fd 上的註冊事件
-> EPOLL_CTL_DEL:刪除指定 fd 的註冊事件
3. fd:所要操做的文件描述符,也就是要內核事件表中監聽的 fd
4. event:指定所要監聽的事件類型,epoll_event 結構指針類型。
1
2
3
4
5
6
7
struct epoll_even 結構以下:
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 */
};
1
2
3
4
5
6
7
8
9
10
11
其中 events 成員描述事件類型,能夠是如下幾種類型宏的集合:
EPOLLIN:表示對應的文件描述符能夠讀(包括對端SOCKET正常關閉);
EPOLLOUT:表示對應的文件描述符能夠寫;
EPOLLPRI:表示對應的文件描述符有緊急的數據可讀(這裏應該表示有帶外數據到來);
EPOLLERR:表示對應的文件描述符發生錯誤;
EPOLLHUP:表示對應的文件描述符被掛斷;
EPOLLET: 將EPOLL設爲邊緣觸發(Edge Triggered)模式,這是相對於水平觸發(Level Triggered)來講的。
EPOLLONESHOT:只監聽一次事件,當監聽完此次事件以後,若是還須要繼續監聽這個socket的話,須要再次把這個socket加入到EPOLL隊列裏
1
2
3
4
5
6
7
返回值
epoll_ctl 成功時返回 0,失敗則返回 -1,並設置 errno
3 int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout);
等待事件的發生,它在一段超時時間以內等待一組文件描述符上的事件,epoll_wait 函數若是檢測到事件,就將全部就緒的事件從內核事件表(epfd 參數決定)中複製到第二個參數 events 指向的數組中。
參數
(1) epfd
要操做的內核事件表的文件描述符,即 epoll_create 的返回值
(2) events
內核事件表中獲得的檢測事件集合
(3) maxevents & timeout
maxevents 告訴內核 events 的最大 size,timeout 指定超時時間
返回值
成功時返回就緒的文件描述符的個數,失敗返回 -1 並設置 errno
三. epoll 工做模式
epoll 對文件描述符的操做有兩種模式:LT(level trigger)和 ET(edge trigger)。LT 模式是默認模式,LT 模式與 ET 模式的區別以下:
LT模式:電平觸發,當 epoll_wait 檢測到描述符事件發生並將此事件通知應用程序,應用程序能夠不當即處理該事件。下次調用 epoll_wait 時,會再次響應應用程序並通知此事件。
ET模式:邊沿觸發,當 epoll_wait 檢測到描述符事件發生並將此事件通知應用程序,應用程序必須當即處理該事件。若是不處理,下次調用 epoll_wait 時,不會再次響應應用程序並通知此事件。
ET 模式在很大程度上減小了 epoll 事件被重複觸發的次數,所以效率要比 LT 模式高。epoll 工做在 ET 模式的時候,必須使用非阻塞套接口,以免因爲一個文件句柄的阻塞讀/阻塞寫操做把處理多個文件描述符的任務餓死。————————————————版權聲明:本文爲CSDN博主「歲月斑駁7」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。原文連接:https://blog.csdn.net/qq_19923217/article/details/81943705