Linux中epoll簡單使用

2021-10-06 07:52:26 字數 2955 閱讀 5527

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...