1. 程式人生 > 其它 >水平觸發和邊緣觸發

水平觸發和邊緣觸發

epoll既支援水平觸發也支援邊緣觸發,預設是水平觸發。


水平觸發(LT)

當被監控的檔案描述符上有可讀寫事件發生時,會通知使用者程式去讀寫,他會一直通知使用者,如果這個描述符是使用者不關心的,它每次都返回通知使用者。

讀緩衝區不為空時, 讀事件觸發。寫緩衝區不為滿時, 寫事件觸發。

水平觸發時,邏輯簡單,不太容易出bug。

寫資料時,LT模式需要先開啟EPOLLOUT,當沒有資料需要寫出時,再關閉EPOLLOUT(否則會一直返回EPOLLOUT事件)。


邊緣觸發(ET)

當被監控的檔案描述符上有可讀寫事件發生時,會通知使用者程式去讀寫,它只會通知使用者程序一次,這需要使用者一次把內容讀取完。如果使用者一次沒有讀完資料,再次請求時,不會立即返回,需要等待下一次的新的資料到來時才會返回,這次返回的內容包括上次未取完的資料。

讀緩衝區狀態變化時, 讀事件觸發。寫緩衝區狀態變化時, 寫事件觸發。(只會提示一次)

邊緣觸發時,業務上層處理的邏輯較為複雜,處理不當存在丟失事件的風險。

寫資料時,ET模式可以便捷地處理EPOLLOUT事件,省去開啟與關閉EPOLLOUT的epoll_ctl(EPOLL_CTL_MOD)呼叫。


區別

水平觸發和邊緣觸發的區別:實質上是排程策略

例如,兩條線分別有資料ABC、DEF,水平觸發的處理順序ADBECF,邊緣觸發的處理順序ABCDEF。


選擇

nginx使用邊緣觸發。redis使用邊水平觸發。為什麼?

如果server的響應通常較小,不會觸發EPOLLOUT,那麼適合使用LT,例如redis等。

而nginx作為高效能的通用伺服器,網路流量可以跑滿達到1G,這種情況下很容易觸發EPOLLOUT,則使用ET。

listenfd建議使用LT,connfd看情況選擇,一般用LT即可,流量大的場景使用ET。