epoll是linux核心為處理大批量控制代碼而作了改進的poll,是linux下多路復用io介面select/poll的增強版本,它能顯著減少程式在大量併發連線中只有少量活躍的情況下的系統cpu利用率。
epoll預設的工作模式是level triggered,簡稱lt即水平觸發模式。是一種預設的工作方式,支援block和no-block socket。
在這種工作模式中,核心會通知你乙個檔案描述符是否就緒了,如果就緒了,你可以對其進行io操作,但是如果你不做任何操作的話,核心會繼續通知你。
epoll另一種工模式是edge triggered,簡稱et即邊緣觸發模式。是一種高速的工作方式,支援no-block socket.
在這種工作模式中,當描述符從未就緒狀態變為已就緒狀態時,核心會通知你。
但是需要注意的是如果描述符一直沒有進行io操作(使其在次變為未就緒狀態),那麼核心就不會在傳送更多通知了。
通過epoll_create1來進行建立,函式定義如下:
#include int epoll_create(int size);
int epoll_create1(int flags);
這兩個函式都可以建立epoll,第乙個函式引數指的是要監聽的數目一共有多少個,這個函式在linux2.6.8之後,被忽略了,建議用epoll_create1(0)這種方法,而且epoll_create1(epollcloexec)建立的epoll可以在執行後關閉。
成功時,返回建立好的epoll控制代碼,失敗時返回-1,錯誤資訊可以通過errno獲得。
記得用close()關閉建立出來的epoll控制代碼,,否則可能導致系統fd被耗盡。
使用函式epoll_ctl,函式定義如下:
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
引數epfd:epoll_create()函式返回的epoll控制代碼
引數op:操作選項
op可選值有以下3個:
epoll_ctl_add:註冊新的fd到epfd中
epoll_ctl_mod:修改已經註冊的fd的監聽事件
epoll_ctl_del:從epfd中刪除乙個fd
引數fd:要進行操作的目標檔案描述符
引數event:struct epoll_event結構指標,將fd和要進行的操作關聯起來
返回值:0成功,-1失敗,錯誤資訊可以通過errno獲得。
再來看一下epoll_event結構體的定義:
typedef union epoll_data epoll_data_t;
struct epoll_event ;
evets可選值有以下幾個:
epollin :表示對應的檔案描述符可以讀
epollout:表示對應的檔案描述符可以寫
epollpri:表示對應的檔案描述符有緊急的資料可讀
epollerr:表示對應的檔案描述符發生錯誤
epollhup:表示對應的檔案描述符被結束通話
epollet: 將epoll設為邊緣觸發模式,這是相對於水平觸發來說的
epolloneshot:只監聽一次事件,當監聽事件完成後,就不在監聽
data是使用者資料變數,可以傳一些資料,在事件監聽的時候拿到。
使用函式epoll_wait,函式定義如下:
int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
引數epfd:epoll_create()函式返回的epoll控制代碼
引數events:struct epoll_event結構指標,事件被觸發後返回的事件集合
引數 maxevents:最大監聽的事件數目
引數 timeout: 等待時的超時時間,以毫秒為單位。
返回值:成功時,返回需要處理的事件數目。呼叫失敗時,返回0,表示等待超時,返回-1,出現錯誤
這個**的功能在子執行緒中每隔兩秒寫入資料,主線程中使用epoll_wait監聽寫入事件,事件觸發後讀取資料輸出。
但是我執行一直有問題,報錯「bad file descriptor」,不知道什麼原因,請大神給看一下。
#include#include#include#include#include #include//檔案描述符
int fd = -1;
//執行緒執行函式
void* callback(void* data)
printf("fd is %d write data %ld\n",fd,write_data);
sleep(2); //睡眠兩秒
}}int main(int argc,char* ar**)
printf("fd %d\n",fd);
int handle = epoll_create1(0);
if(handle == -1)
struct epoll_event ev;
struct epoll_event event;
memset(&ev,0,sizeof(struct epoll_event));
ev.data.fd = fd;
ev.events = epollin|epollet;
int ret = epoll_ctl(handle,epoll_ctl_add,fd,&ev);
if(ret == -1)
//開啟執行緒
pid_t pid;
pthread_create(&pid, null,callback,null);
uint64_t value;
while(1)
}else
}close(fd);
close(handle);
return 0;
}
EPOLL的簡單使用
epoll是linux下的乙個處理多路i o復用的機制,基於事件通知,能夠高效的處理多個socket連線。使用epoll,基本的函式只有三個 1 建立 epoll create 2 控制 epoll ctl 3 監聽 epoll wait 2.1 建立 函式原型 int epoll create i...
epoll使用簡單分析
前面說了下select和poll的優缺點及使用,現在說說linux最新的epoll機制,同樣,如有不足或錯誤之處,還請各位道友指導 epoll機制共有三個函式 epoll create int size 建立乙個epoll實體,size是提示核心內部結構的大小,並無大礙 size在linux ker...
Linux中的epoll機制
linux中的epoll機制的作用 用於一次監聽多個描述符的可讀可寫狀態,而不需要為每個描述符建立乙個執行緒。相關的api int epoll create int max fds 傳遞的引數為可監聽的最大描述符數量,返回乙個epoll物件描述符。int epoll ctl int epfd,int...