青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

論epoll的使用

   前幾天回答一個問題,是關于我們項目中使用的epoll模式的,因為記不大清了,感覺應該使用的就是epoll的高速模式,也就是ET(edge-trigger)模式。這兩天閑暇的時候,打開代碼又看了一下,在epoll事件注冊時并未標記ET模式,看來實際使用的是epoll默認的LT(level-trigger )模式,為什么呢?使用LT意味著 只要 fd 處于 readable/writable 狀態,每次 epoll_wait 時都會返回該 fd,系統開銷不說,自己處理時每次都要把這些fd輪詢一遍,如果fd很多的話,不管這些fd有沒有事件發生,epoll_wait 都會觸發這些fd的輪詢判斷。
   查閱了一些資料,才知道常用的事件處理庫很多都選擇了 LT 模式,包括大家熟知的libevent和boost::asio等,為什么選擇LT呢?那就不得不從ET的弊端的弊端說起。
   ET模式下,當有事件發生時,系統只會通知你一次,也就是調用epoll_wait 返回fd后,不管事件你處理與否,或者處理完全與否,再調用epoll_wait 時,都不會再返回該fd,這樣programmer要自己保證在事件發生時及時有效的處理完。比如此時fd發生了EPOLLIN事件,在調用epoll_wait 后發現此事件,programmer要保證在本次輪詢中對此fd進行了讀操作,并且還要循環調用recv操作,一直讀到recv的返回值小于請求值,或者遇到EAGAIN錯誤,不然下次輪詢時,如果此fd沒有再次觸發事件,你就沒有機會知道這個fd需要你的處理。這樣無形中就增加了programmer的負擔和出錯的機會。
   ET模式的短處正是LT模式的長處,無論此fd是否有事件發生,或者有事件未處理完,每次epoll_wait 時總會得到此fd供你處理。顯而易見,OS在LT模式下維護的 ready list 的大小肯定比ET模式下長,而且你自己輪詢所有的fd時也要比ET下要多,這種消耗和ET模式下循環調用處理函數(如recv和send等),還要邏輯處理是否處理完畢,理論上應該是LT更大一些,不過個人感覺應該差別不會太大。但是LT模式下帶來的邏輯處理的方便性和不易出錯性,讓我們有理由把它作為首選。我想這可能也是為什么epoll后來在ET的基礎上又增加了LT,并且將其作為默認模式的原因吧。
   peakflys 上述觀點,歡迎 志同道合或志同道不合的朋友拍磚。
   PS:文中一味寫LT的好處,沒有說LT 極易引起的寫觸發 頻繁通知的問題,具體大家可以參考評論部分,再次感謝大家的指教。

posted on 2012-08-26 18:33 peakflys 閱讀(12803) 評論(18)  編輯 收藏 引用 所屬分類: 服務器

評論

# re: 論epoll的使用[未登錄] 2012-08-27 10:33 春秋十二月

LT模式下,只要空間可寫,則寫事件不斷被觸發,CPU占用較高,如果不轉為ET模式,怎么解決這一問題?  回復  更多評論   

# re: 論epoll的使用[未登錄] 2012-08-27 16:36 春秋十二月

@peakflys
fd寫事件被觸發,是因為sock底層緩沖區有大于某個閾值的空閑空間,和應用層有無數據待寫沒有關系吧  回復  更多評論   

# re: 論epoll的使用 2012-08-28 10:51 peakflys

@春秋十二月
謝謝春秋仁兄的指教,我是這么認為的。send buffer不滿時觸發的寫事件,應該不至于引起CPU的占用過高(OS里本身也有很多納秒級的死循環),如果過高說明輪詢時的處理函數太耗CPU了,應該是可以優化的,另外輪詢時間也可以設置的長一些,當然有些應用需要這么準確、及時。如果這樣的話,我認為可以這樣改進:在一次網絡主循環里調用兩次epoll_wait,第一次是及時的(例如1ms)用于處理讀和錯誤事件,第二次是稍微長的(例如30~50ms,視情況定)用于處理讀、寫等事件。為了達到這種效果,我們可以 封裝兩種send方式,一種是使用epoll觸發的寫,另外一種是緊急的立即寫(當然寫時可以調用poll等檢測一下是否可寫)。這樣效率應該跟得上了,復雜度和出錯成都也沒有ET模式高。  回復  更多評論   

# re: 論epoll的使用 2012-08-29 17:07 唐詩

樓主沒有說到重點,需要注意的是寫事件。
a. 對于et來說,應用層向tcp緩沖區寫,有可能應用層數據寫完了,但是tcp緩沖沒有寫到EAGAIN事件,那么此時需要在應用層做個標記,表明tcp緩沖區是可寫的,否則,由于et是只觸發一次,應用層就再也不會被通知緩沖區可寫了。
b. 對于lt來說,應用層確實會每次通知可寫事件,問題在于,如果應用層沒數據需要往Tcp緩沖區寫的話,epoll還是會不停的通知你可寫,這時候需要把描述符移出epoll,避免多次無效的通知
http://www.cnblogs.com/egametang/archive/2012/07/30/2615808.html  回復  更多評論   

# re: 論epoll的使用 2012-08-29 17:08 唐詩

事實上et要比lt簡單的多  回復  更多評論   

# re: 論epoll的使用 2012-08-30 07:34 peakflys

謝謝唐詩的回復和指教,你指出的
a問題:在文中寫ET模式時已經說了一部分,不過沒有說寫事件處理完之后,send buffer仍然可寫時怎么處理,因為這個本身就是我認為的ET模式弊端之一,因為挺麻煩也挺易出錯。
b問題:當時寫這篇短文時確實沒有特別考慮,不過在評論里面 春秋十二月仁兄指出了這個問題,唐詩兄給出的方法是每次把數據寫完之后把它移出epoll監聽隊列,以后有新的寫數據時再加入寫事件到隊列,不過個人感覺這種方法不是很理想,除了自己寫著難受之外,因為從2.6.10內核之后 epoll內部隊列的數據結構變成了RB_TREE,游戲中寫數據很頻繁(尤其是大規模玩家在線時),這樣頻繁的調整RB_TREE,性能損耗應該會不小。我在給春秋十二月仁兄的回復中給出了我的大致解決方法(參看上面評論),有什么不完整或者不對的地方,還請唐詩兄指教或者郵件交流 peakflys@gmail.com
至于唐詩兄說的et要比lt簡單,這個可能是用et用的多了,很多細節錯誤已經有了自己固定成熟的解決方案了才說出這樣的結論。ET如果保證每次觸發的事件都可以及時有效的處理完全(當然 個人認為不容易,有時候還要自己處理一些本該TCP處理的東西)ET模式還是可以作為首選的,否則會表現出通訊過程中應用上層各種詭異的問題…… @唐詩  回復  更多評論   

# re: 論epoll的使用 2012-08-30 11:09 唐詩

正因為覺得移出epoll隊列不好,但是不移除也不好,所以et是比較好的方式
代碼其實相當簡單。

write_list_是應用層緩沖區,在epoll寫事件來的時候,應用層緩沖區為空的話
設置socket 可寫。下次往應用層緩沖區寫數據時,檢查socket是否可寫,如果可寫則調用HandleWrite即可。緩沖區寫滿的時候設置socket不可寫就行了。

HandleWrite有兩個調用途徑,一個是寫事件觸發,一個是應用層觸發(socket有is_writable標記)。

void HandleWrite()
while (true) {
// 應用層緩沖區全部寫到TCP緩沖區了, 此時TCP緩沖區還是可寫
// et模式下不會再通知應用層, 所以設置下socket writable狀態
// 下次應用層數據來的時候檢查該狀態
if (write_list_.TotalSize() == 0) {
socket_.set_is_writable(true);
return;
}
int n = write(fd, write_list_.ReadPoint(), write_list_.readable_size());
const int error_no = errno;
if (n == -1) { // 寫異常
if (error_no == EINTR) {
continue;
}
// 緩沖區已寫滿, 需要等寫事件
if (error_no == EAGAIN) {
socket_.set_is_writable(false);
return;
} else {
HandleError(error_no);
return;
}
} else { // 寫正常
write_list_.ReadAdvance(n);
}
}  回復  更多評論   

# re: 論epoll的使用 2012-08-30 14:11 peakflys

恩,唐詩兄在socket上加入標記位的辦法是可以很好解決ET模式的寫問題(上述代碼中唐詩兄應該加上write之后 0==n 的情況,及時斷掉正常中斷的socket,而不是認為寫正常,馬上調整發送緩存)
謝謝唐詩兄的指教,不過如果使用LT模式,唐詩兄會發現更簡單,呵呵。不知道你們一個網絡主線程掛載多少socket? @唐詩
  回復  更多評論   

# re: 論epoll的使用 2012-08-30 14:53 唐詩

@peakflys
單線程,壓力測試流量很大,3K都沒有問題,這時已經受到帶寬限制了。流量小點10K都可以。我們設計只需要1K連接就行了,不夠可以加多個網關服,所以綽綽有余了  回復  更多評論   

# re: 論epoll的使用 2012-08-30 15:48 peakflys

恩,看來服務器性能還不錯,我們單網關設計是5K連接,不過使用的是線程池,單個線程掛512個socket,在加上網絡主循環有相應優化,所以LT模式影響不大,留給上層邏輯很大的擴展空間 @唐詩
  回復  更多評論   

# re: 論epoll的使用[未登錄] 2012-08-31 01:04 春秋十二月

唐工的方法,和我實踐中基本是一樣的,但沒有加標記,而是直接發,如果碰到EAGAIN,則入隊;如果發了一部分,則剩下的部分入隊,留在下次寫事件中發。
簡言之,ET模式的讀寫,需要不斷讀或寫直到遇到EAGAIN或出錯,也就是達到邊緣狀態(空間空或滿),如果后來空間非空或非滿(原因是網絡收到數據或寫出數據),則讀或寫事件,就被觸發一次了。  回復  更多評論   

# re: 論epoll的使用 2012-09-01 15:49 zuhd

一直用的是LT,最大鏈接4K,并且沒有把 “沒有寫需求的socket”移出epoll,目前也沒有發現效率問題。在思考是輪詢的代價大還是移除的代價大?  回復  更多評論   

# re: 論epoll的使用 2012-09-02 11:36 peakflys

@zuhd
移出的代價必然大于輪詢的代價,但是如果LT模式不做寫事件優化的話,是在一定程度上影響效率的(影響的程度和掛載的socket數量有關),這種影響首先表現在輪詢的次數上,其次(也應該說主要)是你的發送函數上調用上,因為不管有沒有消息需要發送,只要send buffer不滿,寫事件都會觸發,你所封裝的發送函數都會調用。  回復  更多評論   

# re: 論epoll的使用 2013-02-26 16:28 peakflys

經過討論最終結論我認為:ET模式在網絡層方面的效率肯定比LT要高。
主要表現在:
1、網絡IO比較小時,send buffer表現為一直可寫,如果網絡主循環沒有延時操作的話,epoll_wait每次調用都會馬上有事件返回,導致不必要的CPU空耗,如果加入延時處理,對于一些實時性要求比較高的操作會受到影響,必須耗費額外的邏輯處理。
2、在網絡IO比較大,尤其是連接數比較多的時候,每次epoll_wait調用時LT模式肯定比ET模式多,因為之后需要對ready list 進行遍歷處理,如果處理邏輯比較復雜,或者之前反饋的事件數LT比ET多很多的話,這時候效率差異就比較明顯了。

ET模式在網絡主循環處理的效率肯定比LT模式要高,至于高多少,視具體應用和具體實現而定。當然ET模式的代價就是增加了網絡層的邏輯處理復雜度,必須手動維護fd當前的狀態,在數據發送時也不能像LT模式那樣直接丟到fd應用層的buffer中。當然武器是好武器,關鍵還是看用的人,如果非要把寶劍當菜刀使,那也只能沉默了……  回復  更多評論   

# re: 論epoll的使用 2013-03-01 22:09 Render Donkey

http://www.shnenglu.com/Leaf/archive/2013/02/25/198061.html
我在博客中,也發表了類似的討論。 博主給了此文鏈接,我順道看過來。
那我也說說我現在的看法。

首先,ET模式比LT模式在處理網絡IO的時候,ET效率高,這個大家已經沒有太多爭論了。

而ET模式換來的代價,就是需要循環讀取。 而寫事件的監測,在我們項目中也是采用的標記法。

我們是按幀發送網絡數據的。
當發送數據時發現標志可寫,就將寫緩沖區中的數據寫向SOCKET。
可寫標記僅當寫的時候發現不可寫時,設置為false,而由epoll_wait觸發變為true. 除此沒有其它改變這個標志的地方。


我想不管是采用LT還是采用ET,都是有原因的。 或者是項目歷史原因,又或者是個人習慣不同。

很多人覺得自己用了LT也沒有發現問題。 這也是證明了LT是可行的。
不過話又說回來。 SELECT時代,不依然有高并發的服務器存在么。

所以,LT是可行的,這個肯定毋庸置疑。并且LT后于ET模式出現,也是有其客觀存在的意義的。
但ET模式也有很多人在用,特別是一些追求效率到扣門兒的兄弟中更為多見。


總之,從各位大大的評論中,我理清了這兩個東西的關系。 也學會用正確的眼光來看待這兩個東西。謝謝大家。  回復  更多評論   

# re: 論epoll的使用 2014-08-06 17:25 呆賊

@peakflys
對于LT下空轉的問題,如果socket有寫事件,不要直接放入epoll中,先send,如果出現eagain再放到epoll中處理,這樣做您看如何?  回復  更多評論   

# re: 論epoll的使用[未登錄] 2014-08-06 18:53 peakflys

@呆賊
“如果socket有寫事件,不要直接放入epoll中”?
你的意思應該是epoll不監聽寫事件吧?
如果是這個意思的話,你說的可以解決LT模式下CPU空轉的問題,不過會引入新的問題,也就是頻繁地修改epoll事件(剛開始EPOLL_OUT不監聽,后來send失敗后Add EPOLL_OUT事件,等監聽發送完畢,還要再Del掉EPOLL_OUT事件).
  回復  更多評論   

<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

導航

統計

公告

人不淡定的時候,就愛表現出來,敲代碼如此,偶爾的靈感亦如此……

常用鏈接

留言簿(4)

隨筆分類

隨筆檔案

文章檔案

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美一区日本一区韩国一区| 亚洲日本在线观看| 欧美影院午夜播放| 午夜精品视频| 国产一区二区三区日韩欧美| 国产日韩在线一区二区三区| 欧美一级大片在线免费观看| 欧美有码视频| 亚洲日本视频| 一个人看的www久久| 国产精品国色综合久久| 欧美在线看片| 美女脱光内衣内裤视频久久网站| 亚洲精品久久久久久久久久久| 亚洲国产精品久久久久秋霞影院 | 欧美成人性生活| 欧美黑人国产人伦爽爽爽| 亚洲少妇最新在线视频| 亚洲欧美日韩在线高清直播| 狠狠综合久久av一区二区小说| 欧美激情在线播放| 国产精品国码视频| 欧美成va人片在线观看| 欧美视频中文字幕在线| 久久裸体视频| 欧美日韩一区视频| 欧美va天堂va视频va在线| 欧美日韩亚洲91| 麻豆av福利av久久av| 欧美三日本三级少妇三2023| 久久亚洲欧美国产精品乐播| 欧美日本一区| 欧美77777| 国产精品毛片大码女人| 亚洲国产成人不卡| 国色天香一区二区| 亚洲性感激情| 夜夜精品视频一区二区| 久久久久久穴| 久久激情五月婷婷| 欧美日韩一区视频| 欧美激情按摩在线| 黄色成人av| 亚洲欧美激情诱惑| 亚洲伊人一本大道中文字幕| 欧美成人福利视频| 免费成人美女女| 国产亚洲一区二区在线观看| 一二美女精品欧洲| 一本色道久久99精品综合| 麻豆av一区二区三区久久| 久久久久欧美| 国产亚洲制服色| 午夜亚洲精品| 欧美一区二区三区视频在线 | 韩国福利一区| 性久久久久久| 久久精品欧美日韩精品| 国产毛片一区二区| 亚洲欧美日韩国产综合精品二区| 亚洲天堂成人| 国产精品jvid在线观看蜜臀 | 欧美大片专区| 亚洲国产中文字幕在线观看| 久久色在线播放| 免费看黄裸体一级大秀欧美| 久久伊人精品天天| 欧美va亚洲va日韩∨a综合色| 精久久久久久| 久久综合网络一区二区| 欧美激情精品久久久久久大尺度| 亚洲国产网站| 欧美精品电影在线| 正在播放亚洲一区| 欧美一区二区免费| 国产亚洲综合在线| 久久视频精品在线| 亚洲黄色在线看| 亚洲午夜小视频| 国产嫩草影院久久久久| 久久成人国产精品| 欧美国产成人在线| 亚洲一区在线观看视频 | 久久久午夜视频| 欧美肥婆在线| 亚洲一区二区精品在线| 国产情侣一区| 模特精品在线| 亚洲图片欧洲图片av| 久久九九电影| 亚洲精品中文字幕有码专区| 欧美午夜电影在线| 久久精品视频亚洲| 亚洲精选一区| 久久久久久有精品国产| 亚洲人www| 国产欧美一区二区精品忘忧草| 久久综合九色欧美综合狠狠| 亚洲欧洲一区二区天堂久久 | 亚洲免费福利视频| 久久久久亚洲综合| 在线视频欧美日韩精品| 国产一区二区成人久久免费影院| 美日韩丰满少妇在线观看| 亚洲视频欧洲视频| 欧美福利小视频| 久久精品99国产精品| 亚洲精选大片| 激情成人中文字幕| 国产精品美女一区二区| 麻豆91精品91久久久的内涵| 亚洲午夜日本在线观看| 亚洲国产精品久久久久秋霞蜜臀 | 日韩一区二区久久| 欧美成人国产一区二区 | 亚洲国产三级网| 国产日韩精品一区| 欧美三日本三级三级在线播放| 老司机一区二区三区| 亚洲欧美日韩综合| 一区二区冒白浆视频| 亚洲国产成人tv| 免费在线国产精品| 久久九九久精品国产免费直播| 亚洲一区二区黄色| 中文国产亚洲喷潮| 亚洲精选91| 亚洲精品一区在线| 亚洲国产精品一区二区第四页av| 国产一区二区福利| 国产欧美精品日韩精品| 国产精品色午夜在线观看| a4yy欧美一区二区三区| 亚洲国产裸拍裸体视频在线观看乱了中文 | 日韩一区二区精品葵司在线| 亚洲黄色在线看| 亚洲国产精品视频一区| 精品盗摄一区二区三区| 激情综合在线| 亚洲电影av在线| 亚洲二区在线视频| 亚洲电影免费观看高清完整版| 激情视频亚洲| 在线观看日产精品| 亚洲经典在线| 99国产精品久久久久久久成人热| 亚洲精品国产精品乱码不99| 亚洲精品九九| 在线一区二区日韩| 亚洲影院免费观看| 欧美在线视频全部完| 久久久免费观看视频| 久久综合伊人77777蜜臀| 蜜臀va亚洲va欧美va天堂| 欧美激情按摩| 99精品福利视频| 亚洲在线免费观看| 久久国产精品亚洲77777| 久久综合福利| 欧美人与禽猛交乱配| 国产精品久久久久久久9999| 国产欧美日韩一级| 一色屋精品视频在线看| 亚洲精品美女在线观看| 中文网丁香综合网| 久久xxxx精品视频| 亚洲第一网站| 正在播放日韩| 久久免费高清| 欧美日韩专区| 一区二区在线看| 在线午夜精品自拍| 久久手机精品视频| 亚洲精品午夜精品| 欧美一区二区三区四区在线观看| 免费看的黄色欧美网站| 国产精品久久久久久久久果冻传媒| 国产一区二区三区在线免费观看 | 国产精品99久久久久久有的能看 | 麻豆成人在线观看| 国产精品久久久久久久9999| 在线精品视频一区二区三四| 亚洲最黄网站| 麻豆精品网站| 亚洲香蕉伊综合在人在线视看| 久久女同互慰一区二区三区| 欧美婷婷久久| 亚洲精品国产日韩| 久久久亚洲精品一区二区三区| 日韩图片一区| 你懂的国产精品| 好看不卡的中文字幕| 亚洲自拍偷拍网址| 亚洲国产岛国毛片在线| 亚洲欧美资源在线| 国产精品99免费看 | 欧美日韩在线免费视频| 一个人看的www久久| 免费亚洲电影在线| 狠狠色丁香婷综合久久|