2012-02-06 55 views
40

從epoll的的手冊頁:epoll邊緣觸發選項的目的是什麼?

epoll is a variant of poll(2) that can be used either as an edge-triggered 
or a level-triggered interface 

當將一個使用邊沿觸發選項?手冊頁給出了一個使用它的例子,但我不明白爲什麼它在這個例子中是必要的。

回答

77

當FD變爲讀取或寫入準備好了,你不一定要讀(或寫)的所有數據立即。

只要FD仍然準備好,水平觸發的epoll就會一直嘮叨你,而邊緣觸發不會再打擾你,直到下一次你得到一個EAGAIN(所以編碼更復雜,但可以是根據你需要做什麼來提高效率)。

說你從資源到FD寫作。如果您註冊您對該FD的興趣準備就緒,可以通過電平觸發,您將會收到關於FD仍處於寫入準備狀態的通知。如果資源尚不可用,那就是浪費喚醒,因爲無論如何你都不能再寫任何東西。

如果你要添加爲邊沿觸發,而不是,你會得到通知的FD是準備寫一次,那麼當其他資源準備好你寫的東西,你可以。然後,如果write(2)返回EAGAIN,則停止寫入並等待下一個通知。

這同樣適用於閱讀,因爲你可能不希望把所有的數據到用戶空間,你就可以做任何你想用它做之前(因此具有緩衝它,等等等等)。使用邊緣觸發的epoll可以在準備好讀取時告訴它,然後可以記住這一點,並在「當時」進行實際閱讀。

+3

這是邊沿觸發的行爲對安全的比賽條件,例如如果數據變得可用後'讀'失敗'EAGAIN',但在'epoll'被調用之前? – 2012-02-06 16:45:52

+0

當然。如果FD已經準備就緒,並且您尚未收到通知,則「epoll」會立即返回。 – 2012-02-06 17:10:08

+17

ET對於多核機器上的多線程服務器也特別好。您可以爲每個核心運行一個線程,並讓所有這些線程在同一個epfd上調用epoll_wait。當數據進入fd時,恰好有一個線程會被喚醒來處理它。 – 2012-02-06 19:51:24

3

在我的實驗中,ET並不保證只有一個線程被喚醒,雖然它往往只喚醒一個。 EPOLLONESHOT標誌就是爲了這個目的。

+2

'man 7 epoll':即使使用邊緣觸發的'epoll',在接收到多個數據塊時可以生成多個事件,調用者可以選擇指定'EPOLLONESHOT'標誌,告訴'epoll'禁用使用'epoll_wait(2)'接收事件後的相關文件描述符。當指定'EPOLLONESHOT'標誌,這是調用者的責任使用'epoll_ctl(2)重新武裝文件描述符'和'EPOLL_CTL_MOD'。 – zeekvfu 2014-05-17 05:27:01

+1

準確地說,每上升一次您會收到通知。如果您將epdin添加到EPOLLET中,每次按下Enter鍵都會生成一個事件。這就是爲什麼需要EPOLLONESHOT。 – Guido 2014-06-11 23:12:51