天天看點

Epoll之ET、LT模式

Epoll之ET、LT模式

在使用epoll時,在函數 epoll_ctl中如果不設定,epoll_event 的event預設為LT(水準觸發)模式。

使用LT模式意味着隻要fd處于可讀或者可寫狀态,每次epoll_wait都會傳回該fd,這樣的話會帶來很大的系統開銷,且處理時候每次都需要把這些fd輪詢一遍,如果fd的數量巨大,不管有沒有事件發生,epoll_wait都會觸發這些fd的輪詢判斷。

         在ET模式下,當有事件發生時,系統隻會通知你一次,即在調用epoll_wait傳回fd後,不管這個事件你處理還是沒處理,處理完沒有處理完,當再次調用epoll_wait時,都不會再傳回該fd,這樣的話程式員要自己保證在事件發生時要及時有效的處理完該事件。例如:fd發生了IN事件,在調用epoll_wait後發現了該時間,程式員要保證在本次輪詢中對該fd做了讀操作,且還要循環調用recv操作,直到讀到的recv的傳回值小于請求值,或者遇到EAGAIN錯誤,否則,在下次輪詢時,如果該fd沒有再次觸發事件,你就沒有機會知道這個fd需要處理。這樣就會增加程式員的負擔和出錯的機會(可能有些資料沒有來得及處理,丢失資料)。

         在LT模式下,無論fd是否有事件發生,或者還有一些事件沒有處理完,每次調用epoll_wait時,總會得到該fd讓你處理(隻要有沒事件沒有處理,會一直通知你處理,直到你處理完為止,這樣就保證了資料的不丢失)。

         作業系統在LT模式下維護的就緒隊列大小相對于ET模式肯定大,且LT輪詢所有的fd總比ET輪詢的fd大。自然在性能上LT不如ET,但是在使用ET模式的時,需要循環調用recv,send等處理函數,得保證其事件處理完畢,這樣也會帶來開銷且容易出錯。

從 kernel 代碼來看,ET/LT模式的處理邏輯幾乎完全相同,差别僅在于 LT模式在 event 發生時不會将其從 ready list 中移除,略為增大了event 處理過程中 kernel space 中記錄資料的大小。

總結:

1. epoll 的 ET和 LT 模式處理邏輯差異極小,性能測試結果表明正常應用場景中二者性能差異可以忽略。

2. 使用 ET 的程式比使用LT 的邏輯複雜,出錯機率更高。

3. ET 和LT 的性能差異主要在于 epoll_wait 系統調用的處理速度,是否是程式的性能瓶頸需要視應用場景而定,不可一概而論。

         個人建議使用LT模式

參考資料:

http://www.cppblog.com/peakflys/archive/2012/08/26/188344.aspx

http://www.cppblog.com/Leaf/archive/2013/02/25/198061.html

繼續閱讀