水平觸發(fā)和邊緣觸發(fā)
epoll既支持水平觸發(fā)也支持邊緣觸發(fā),默認(rèn)是水平觸發(fā)。
水平觸發(fā)(LT)
當(dāng)被監(jiān)控的文件描述符上有可讀寫事件發(fā)生時,會通知用戶程序去讀寫,他會一直通知用戶,如果這個描述符是用戶不關(guān)心的,它每次都返回通知用戶。
讀緩沖區(qū)不為空時, 讀事件觸發(fā)。寫緩沖區(qū)不為滿時, 寫事件觸發(fā)。
水平觸發(fā)時,邏輯簡單,不太容易出bug。
寫數(shù)據(jù)時,LT模式需要先打開EPOLLOUT,當(dāng)沒有數(shù)據(jù)需要寫出時,再關(guān)閉EPOLLOUT(否則會一直返回EPOLLOUT事件)。
邊緣觸發(fā)(ET)
當(dāng)被監(jiān)控的文件描述符上有可讀寫事件發(fā)生時,會通知用戶程序去讀寫,它只會通知用戶進程一次,這需要用戶一次把內(nèi)容讀取完。如果用戶一次沒有讀完數(shù)據(jù),再次請求時,不會立即返回,需要等待下一次的新的數(shù)據(jù)到來時才會返回,這次返回的內(nèi)容包括上次未取完的數(shù)據(jù)。
讀緩沖區(qū)狀態(tài)變化時, 讀事件觸發(fā)。寫緩沖區(qū)狀態(tài)變化時, 寫事件觸發(fā)。(只會提示一次)
邊緣觸發(fā)時,業(yè)務(wù)上層處理的邏輯較為復(fù)雜,處理不當(dāng)存在丟失事件的風(fēng)險。
寫數(shù)據(jù)時,ET模式可以便捷地處理EPOLLOUT事件,省去打開與關(guān)閉EPOLLOUT的epoll_ctl(EPOLL_CTL_MOD)調(diào)用。
區(qū)別
水平觸發(fā)和邊緣觸發(fā)的區(qū)別:實質(zhì)上是調(diào)度策略。
例如,兩條線分別有數(shù)據(jù)ABC、DEF,水平觸發(fā)的處理順序ADBECF,邊緣觸發(fā)的處理順序ABCDEF。
選擇
nginx使用邊緣觸發(fā)。redis使用邊水平觸發(fā)。為什么?
如果server的響應(yīng)通常較小,不會觸發(fā)EPOLLOUT,那么適合使用LT,例如redis等。
而nginx作為高性能的通用服務(wù)器,網(wǎng)絡(luò)流量可以跑滿達到1G,這種情況下很容易觸發(fā)EPOLLOUT,則使用ET。
listenfd建議使用LT,connfd看情況選擇,一般用LT即可,流量大的場景使用ET。

浙公網(wǎng)安備 33010602011771號