epoll的使用總結
使用epoll來實現乙個tcp server,中間碰到了不少使用細節上的問題,總結一下。
man epoll裡推薦的使用方法
#define max_events 10要點:struct
epoll_event ev, events[max_events];
intlisten_sock, conn_sock, nfds, epollfd;
/*set up listening socket, 'listen_sock' (socket(),
bind(), listen())
*/epollfd = epoll_create(10
);
if (epollfd == -1
) ev.events = epollin; //
不要寫成ev.events = epollin | epollet;
ev.data.fd =listen_sock;
if (epoll_ctl(epollfd, epoll_ctl_add, listen_sock, &ev) == -1
)
for(;;)
for (n = 0; n < nfds; ++n)
setnonblocking(conn_sock);
ev.events = epollin |epollet;
ev.data.fd =conn_sock;
if(epoll_ctl(epollfd, epoll_ctl_add, conn_sock,
&ev) == -1
) }
else}}
1.listen_sock使用lt模式,其他使用et模式,這樣就不會遺漏後續的connect請求
(其實還有另外一種方式,listen_sock也使用et模式,只是要用while包裹accept語句,直到返回-1,這裡我們不討論)
在遺落後續的connect請求這個問題上花費了很多時間。
具體測試表現是:1000個client發起tcp connect,並在連線成功之後傳送資料。測試中,1000個client正常連線並傳送資料,但epoll中未收到部分client的連線請求。
使用netstat命令檢視有以下發現:
netstat -apn|grep 7777|wc -l系統已經建立了1000個tcp連線,但是其中有小部分連線不是由我們的程式負責建立的。1001
netstat -apn|grep 7777|grep -|wc -l
139
netstat -apn|grep 7777|grep -使用上面的命令能夠發現,有小部分連線處於established狀態,但程序資訊那一欄卻是"-"
這應該是et模式下連線就緒觸發了一次,但我們的程式沒有來及處理,et不會再觸發,導致這小部分連線再沒有機會得到accept處理。
解決這個問題的話,把listen_sock(負責listen和accept新連線的socket)設成lt模式,這樣沒來得及處理的connect請求會在下次執行到epoll_wait時繼續得到處理。
2.epoll_wait的引數設定
#include
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
maxevents引數越小,相同請求數的情況下,需要呼叫更多次數的epoll_wait來處理這些在epoll佇列裡的請求,可能會有效率損失。
timeout引數:一般設定成-1,即沒有請求時無限等待。
epoll特點總結
2.1 ppc tpc模型 這兩個模型就是有個連線來了就給分配個程序 執行緒,前者肯定更費資源了,因為這麼多程序 執行緒不是吃素的,都要時間和空間,開銷大,所以併發只有幾百?也沒說epoll 是如何分配的?也就是說那兩個得遍歷所有,和連線數有關!epoll也遍歷,但是只遍歷活躍的所以效率高。強調實際...
Epoll實驗總結
2012 09 06 15 54 10 分類 network program 標籤 epoll c 舉報 字型大小 訂閱 我的 書 一 超時實驗 建立乙個阻塞模式的tcp連線到乙個沒有監聽的服務埠 肯定連不上,然後等待超時 然後將這個socket描述符,交由epoll管理。註冊的epoll事件為 e...
epoll監聽檔案 epoll的使用
epoll i o event notification facility 在linux的網路程式設計中,很長的時間都在使用select來做事件觸發。在linux新的核心中,有了一種替換它的機制,就是epoll。相比於select,epoll最大的好處在於它不會隨著監聽fd數目的增長而降低效率。因為...