q:網路伺服器的瓶頸在哪?
a:io效率。
自從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為我們帶來了什麼
epoll為我們帶來了什麼 epoll的操作就這麼簡單,總共不過4個api epoll create,epoll ctl,epoll wait和close.但凡作過比較深入的網路程式設計的人,都會知道,在win平台下,高效的io模型是iocp,而在linux底下則是epoll。那麼,epoll與io...
EPOLL為我們帶來了什麼
epoll與iocp的異同之處 linux 2.6核心epoll用法舉例說明 linux 2.6核心epoll用法舉例說明 zz from www.csdn.net epoll用到的所有函式都是在標頭檔案sys epoll.h中宣告的,下面簡要說明所用到的資料結構和函式 所用到的資料結構 typed...
C 3 0 為我們帶來什麼(6) 擴充套件方法
在c 3.0中可以出現這樣的語法 int i 2 console.writeline i.square 這就是擴充套件方法。如何使int具有square方法呢?只需要定義這樣乙個函式 public static int square this int i this 表示針對int的例項和索引器的th...