摘要:深入剖析事件有兩種模型水平觸發接收緩沖區不為空有數據可讀讀事件一直觸發發送緩沖區不滿可以繼續寫入數據寫事件一直觸發符合思維習慣,返回的事件就是的狀態邊沿觸發的接收緩沖區狀態變化時觸發讀事件,即空的接收緩沖區剛接收到數據時觸發讀事件的發送緩沖
epoll LT/ET 深入剖析
EPOLL事件有兩種模型:
Level Triggered (LT) 水平觸發
.socket接收緩沖區不為空 有數據可讀 讀事件一直觸發
.socket發送緩沖區不滿 可以繼續寫入數據 寫事件一直觸發
符合思維習慣,epoll_wait返回的事件就是socket的狀態
Edge Triggered (ET) 邊沿觸發
.socket的接收緩沖區狀態變化時觸發讀事件,即空的接收緩沖區剛接收到數據時觸發讀事件
.socket的發送緩沖區狀態變化時觸發寫事件,即滿的緩沖區剛空出空間時觸發讀事件
僅在狀態變化時觸發事件
ET還是LT?
LT的處理過程:
. accept一個連接,添加到epoll中監聽EPOLLIN事件
. 當EPOLLIN事件到達時,read fd中的數據并處理
. 當需要寫出數據時,把數據write到fd中;如果數據較大,無法一次性寫出,那么在epoll中監聽EPOLLOUT事件
. 當EPOLLOUT事件到達時,繼續把數據write到fd中;如果數據寫出完畢,那么在epoll中關閉EPOLLOUT事件
ET的處理過程:
. accept一個一個連接,添加到epoll中監聽EPOLLIN|EPOLLOUT事件
. 當EPOLLIN事件到達時,read fd中的數據并處理,read需要一直讀,直到返回EAGAIN為止
. 當需要寫出數據時,把數據write到fd中,直到數據全部寫完,或者write返回EAGAIN
. 當EPOLLOUT事件到達時,繼續把數據write到fd中,直到數據全部寫完,或者write返回EAGAIN
從ET的處理過程中可以看到,ET的要求是需要一直讀寫,直到返回EAGAIN,否則就會遺漏事件。而LT的處理過程中,直到返回EAGAIN不是硬性要求,但通常的處理過程都會讀寫直到返回EAGAIN,但LT比ET多了一個開關EPOLLOUT事件的步驟
LT的編程與poll/select接近,符合一直以來的習慣,不易出錯
ET的編程可以做到更加簡潔,某些場景下更加高效,但另一方面容易遺漏事件,容易產生bug
這里有兩個簡單的例子演示了LT與ET的用法(其中epoll-et的代碼比epoll要少10行):
https://github.com/yedf/handy/blob/master/raw-examples/epoll.cc
https://github.com/yedf/handy/blob/master/raw-examples/epoll-et.cc
針對容易觸發LT開關EPOLLOUT事件的情景(讓服務器返回1M大小的數據),我用ab做了性能測試
測試的結果顯示ET的性能稍好,詳情如下:
LT 啟動命令 ./epoll a
ET 啟動命令 ./epoll-et a
ab 命令:ab -n 1000 -k 127.0.0.1/
LT 結果:Requests per second: 42.56 [#/sec] (mean)
ET 結果:Requests per second: 48.55 [#/sec] (mean)
當我把服務器返回的數據大小改為48576時,開關EPOLLOUT更加頻繁,性能的差異更大
ab 命令:ab -n 5000 -k 127.0.0.1/
LT 結果:Requests per second: 745.30 [#/sec] (mean)
ET 結果:Requests per second: 927.56 [#/sec] (mean)
對于nginx這種高性能服務器,ET模式是很好的,而其他的通用網絡庫,更多是使用LT,避免使用的過程中出現bug
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/39240.html
摘要:相當于層的初始化。注意,這里是層層自己的消息,與層的沒關系。好吧,這個過程基本上分析完畢了,其實就是通過不斷的處理消息,并且調用消息的回調。 承接上文在looper中會在一開始就創建一個MessageQueue,并且在loop中每次都會從其中取出一個message處理。那么我們就來看看這個MessageQueue: MessageQueue(boolean quitAllowe...
摘要:我們這里以單進程啟動為例中的函數調用這個函數回循環調用中的事件循環的核心函數是。這個方法僅在方法中調用,它是處理,分發事件的核心初始化事件驅動模塊的方法退出事件驅動模塊前調用的方法。讀事件的回調函數是這樣就進入了框架處理流程 我們這里以單進程啟動為例nginx.c中的main 函數調用ngx_single_process_cycle 這個函數回循環調用 ngx_process_cy...
閱讀 1174·2021-09-27 13:34
閱讀 981·2021-09-13 10:25
閱讀 511·2019-08-30 15:52
閱讀 3450·2019-08-30 13:48
閱讀 648·2019-08-30 11:07
閱讀 2167·2019-08-29 16:23
閱讀 1993·2019-08-29 13:51
閱讀 2328·2019-08-26 17:42