IO
IO多路複用
BIO
NIO
select
poll
epoll
水平觸發和邊沿觸發
-
水平觸發只關心檔案描述符中是否還有沒完成處理的資料,如果有,不管怎樣
epoll_wait
,總是會被返回。簡單說——水平觸發代表了一種“狀態”。 -
邊沿觸發只關心檔案描述符是否有新的事件產生,如果有,則返回;如果返回過一次,不管程式是否處理了,只要沒有新的事件產生,
epoll_wait
不會再認為這個fd被“觸發”了。簡單說——邊沿觸發代表了一個“事件”。“
那麼邊沿觸發怎麼才能迫使新事件產生呢?一般需要反覆呼叫
read
/write
這樣的IO介面,直到得到了EAGAIN
錯誤碼,再去嘗試epoll_wait
才有可能得到下次事件。
那麼為什麼需要邊沿觸發呢?
邊沿觸發把如何處理資料的控制權完全交給了開發者,提供了巨大的靈活性。比如,讀取一個http的請求,開發者可以決定只讀取http中的headers資料就停下來,然後根據業務邏輯判斷是否要繼續讀(比如需要呼叫另外一個服務來決定是否繼續讀)。而不是次次被socket尚有資料的狀態煩擾;寫入資料時也是如此。比如希望將一個資源A寫入到socket。當socket的buffer充足時,epoll_wait
會返回這個fd是準備好的。但是資源A此時不一定準備好。如果使用水平觸發,每次經過epoll_wait
也總會被打擾。在邊沿觸發下,開發者有機會更精細的定製這裡的控制邏輯。
但不好的一面時,邊沿觸發也大大的提高了程式設計的難度。一不留神,可能就會miss掉處理部分socket資料的機會。如果沒有很好的根據EAGAIN
來“重置”一個fd,就會造成此fd永遠沒有新事件產生,進而導致餓死相關的處理程式碼。
水平觸發和邊緣觸發