epoll使用例子

2021-04-14 00:22:37 字數 4837 閱讀 3852

自從linux提供了/dev/epoll的裝置以及後來2.6核心中對/dev/epoll裝置的訪問的封裝(system epoll)之後,這種現象得到了大大的緩解,如果說幾個月前,大家還對epoll不熟悉,那麼現在來說的話,epoll的應用已經得到了大範圍的普及。

那麼究竟如何來使用epoll呢?其實非常簡單。

通過在包含乙個標頭檔案#include 

以及幾個簡單的api將可以大大的提高你的網路伺服器的支援人數。

首先通過create_epoll(int maxfds)來建立乙個epoll的控制代碼,其中maxfds為你epoll所支援的最大控制代碼數。這個函式會返回乙個新的epoll控制代碼,之後的所有操作將通過這個控制代碼來進行操作。在用完之後,記得用close()來關閉這個建立出來的epoll控制代碼。

之後在你的網路主迴圈裡面,每一幀的呼叫epoll_wait(int epfd, epoll_event events, int max events, int timeout)來查詢所有的網路介面,看哪乙個可以讀,哪乙個可以寫了。基本的語法為:

nfds = epoll_wait(kdpfd, events, maxevents, -1);

其中kdpfd為用epoll_create建立之後的控制代碼,events是乙個epoll_event*的指標,當epoll_wait這個函式操作成功之後,epoll_events裡面將儲存所有的讀寫事件。max_events是當前需要監聽的所有socket控制代碼數。最後乙個timeout是epoll_wait的超時,為0的時候表示馬上返回,為-1的時候表示一直等下去,直到有事件範圍,為任意正整數的時候表示等這麼長的時間,如果一直沒有事件,則範圍。一般如果網路主迴圈是單獨的執行緒的話,可以用-1來等,這樣可以保證一些效率,如果是和主邏輯在同乙個執行緒的話,則可以用0來保證主迴圈的效率。

epoll_wait範圍之後應該是乙個迴圈,遍利所有的事件:

for(n = 0; n < nfds; ++n) 

setnonblocking(client); // 將新連線置於非阻塞模式

ev.events = epollin | epollet; // 並且將新連線也加入epoll的監聽佇列。

注意,這裡的引數epollin | epollet並沒有設定對寫socket的監聽,如果有寫操作的話,這個時候epoll是不會返回事件的,如果要對寫操作也監聽的話,應該是epollin | epollout | epollet

ev.data.fd = client;

if (epoll_ctl(kdpfd, epoll_ctl_add, client, &ev) < 0) 

} else // 如果不是主socket的事件的話,則代表是乙個使用者socket的事件,則來處理這個使用者socket的事情,比如說read(fd,***)之類的,或者一些其他的處理。

do_use_fd(events[n].data.fd);

} 對,epoll的操作就這麼簡單,總共不過4個api:epoll_create, epoll_ctl, epoll_wait和close。

世界變了,原來擔心的問題,現在已經不是問題了。

epoll與iocp的異同之處

linux 2.6核心epoll用法舉例說明

linux 2.6核心epoll用法舉例說明(zz from www.csdn.net)

epoll用到的所有函式都是在標頭檔案sys/epoll.h中宣告的,下面簡要說明所用到的資料結構和函式:

所用到的資料結構

typedef union epoll_data epoll_data_t;

struct epoll_event ;

結構體epoll_event 被用於註冊所感興趣的事件和回傳所發生待處理的事件,其中epoll_data 聯合體用來儲存觸發事件的某個檔案描述符相關的資料,例如乙個client連線到伺服器,伺服器通過呼叫accept函式可以得到於這個client對應的socket檔案描述符,可以把這檔案描述符賦給epoll_data的fd欄位以便後面的讀寫操作在這個檔案描述符上進行。epoll_event 結構體的events欄位是表示感興趣的事件和被觸發的事件可能的取值為:epollin:表示對應的檔案描述符可以讀;

epollout:表示對應的檔案描述符可以寫;

epollpri:表示對應的檔案描述符有緊急的資料可讀(我不太明白是什麼意思,可能是類似client關閉  socket連線這樣的事件);

epollerr:表示對應的檔案描述符發生錯誤;

epollhup:表示對應的檔案描述符被結束通話;

epollet:表示對應的檔案描述符有事件發生;

所用到的函式:

1、epoll_create函式

函式宣告:int epoll_create(intsize)

該函式生成乙個epoll專用的檔案描述符,其中的引數是指定生成描述符的最大範圍(我覺得這個引數和select函式的第乙個引數應該是類似的但是該怎麼設定才好,我也不太清楚)。

2、epoll_ctl函式

函式宣告:int epoll_ctl(intepfd, intop, intfd, struct epoll_event *event)

該函式用於控制某個檔案描述符上的事件,可以註冊事件,修改事件,刪除事件。

引數:epfd:由epoll_create生成的epoll專用的檔案描述符;

op:要進行的操作例如註冊事件,可能的取值epoll_ctl_add註冊、epoll_ctl_mod

改、epoll_ctl_del刪除

fd:關聯的檔案描述符;

event:指向epoll_event的指標;

如果呼叫成功返回0,不成功返回-1

3、epoll_wait函式

函式宣告:int epoll_wait(intepfd,struct epoll_event *events,intmaxevents,inttimeout)

該函式用於輪詢i/o事件的發生;

引數:epfd:由epoll_create生成的epoll專用的檔案描述符;

epoll_event:用於回傳代處理事件的陣列;

maxevents:每次能處理的事件數;

timeout:等待i/o事件發生的超時值;

返回發生事件數。

例子:#include

#include

#include

#include

#include

#include

#include

#include

#define

maxline 10

#define

open_max 100

#define

listenq 20

#define

serv_port 5555

#define

inftim 1000

void

setnonblocking(int sock)

opts = opts|o_nonblock;

if(fcntl(sock,f_setfl,opts)<0)

}

intmain()

setnonblocking(connfd);

char *str = inet_ntoa(clientaddr.sin_addr);

std::cout<<"connect from "<_u115 ?tr<

//設定用於讀操作的檔案描述符

ev.data.fd=connfd;

//設定用於注測的讀操作事件

ev.events=epollin|epollet;

//註冊ev

epoll_ctl(epfd,epoll_ctl_add,connfd,&ev);

}else

if(events[i].events&epollin)

else

std::cout<<"readline error"<

} else

if (n == 0)

//設定用於寫操作的檔案描述符

ev.data.fd=sockfd;

//設定用於注測的寫操作事件

ev.events=epollout|epollet;

//修改sockfd上要處理的事件為epollout

epoll_ctl(epfd,epoll_ctl_mod,sockfd,&ev);

}else

if(events[i].events&epollout) } }

}epoll_wait執行的原理是

等侍註冊在epfd上的socket fd的事件的發生,如果發生則將發生的sokct fd和事件型別放入到events陣列中。

並且將註冊在epfd上的socket fd的事件型別給清空,所以如果下乙個迴圈你還要關注這個socket fd的話,則需要用epoll_ctl(epfd,epoll_ctl_mod,listenfd,&ev)來重新設定socket fd的事件型別。這時不用epoll_ctl_add,因為socket fd並未清空,只是事件型別清空。這一步非常重要。 

epoll完整例子

include include include include include include include include define maxline 100 void setnonblocking int sock opts opts o nonblock if fcntl sock,f s...

epoll監聽檔案 epoll的使用

epoll i o event notification facility 在linux的網路程式設計中,很長的時間都在使用select來做事件觸發。在linux新的核心中,有了一種替換它的機制,就是epoll。相比於select,epoll最大的好處在於它不會隨著監聽fd數目的增長而降低效率。因為...

epoll使用介紹

linux下的epoll較之傳統的select函式比較其優點 突破了單程序開啟socket描述符最大數目的限制,select單程序開啟fd的資料是有限制的,由fd setsize設定,預設值是2048,而這在那此需要支援上萬連線數目的網路伺服器來說是不能忍受的,雖然這個限制可以通過修改巨集重編譯核心...