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行):
針對容易觸發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
epoll LT ET 深入剖析
epoll lt et 深入剖析 epoll事件有兩種模型 level triggered lt 水平觸發 socket接收緩衝區不為空 有資料可讀 讀事件一直觸發 socket傳送緩衝區不滿 可以繼續寫入資料 寫事件一直觸發 符合思維習慣,epoll wait返回的事件就是socket的狀態 ed...
epoll LT ET 深入剖析
epoll lt et 深入剖析 epoll事件有兩種模型 level triggered lt 水平觸發 socket接收緩衝區不為空 有資料可讀 讀事件一直觸發 socket傳送緩衝區不滿 可以繼續寫入資料 寫事件一直觸發 符合思維習慣,epoll wait返回的事件就是socket的狀態 ed...
epoll LT ET 深度剖析
level triggered lt 水平觸發 socket接收緩衝區不為空 有資料可讀 讀事件一直觸發 socket傳送緩衝區不滿 可以繼續寫入資料 寫事件一直觸發 符合思維習慣,epoll wait返回的事件就是socket的狀態 edge triggered et 邊沿觸發 socket的接收...