epoll水平觸發 邊沿觸發與非阻塞I O模型

2021-10-05 00:12:48 字數 1483 閱讀 3278

epoll作為多路i/o復用在linux的實現,無論是在模型方面,還是執行效率方面,相較於select和poll都有了較大改進。

水平觸發:凡是epoll負責的輸入輸出源緩衝區有資料可讀或者可寫,epoll_wait()就不會阻塞,或者說會通知。

邊沿觸發:凡是epoll負責的輸入輸出源的緩衝區有新的資料可讀,或者舊資料傳送走,epoll_wait()就不會阻塞,或者說會通知。

實際上,兩種觸發方式各有優劣,水平觸發可以不斷地通知使用者區i/o源可用,直到i/o源不可用。

邊沿觸發被通知的事件更少,核心需要處理的響應更少,所以核心開銷更小。

設定乙個檔案描述符為非阻塞i/o以後,再進行read或write,不論i/o源是否可用,均會給出響應。

這種方法的主要優勢在於,不會阻塞使用者態,使用者態可以在i/o源不可用時可以選擇執行其他程式。

劣勢在於,如果通過while的方式不斷檢測i/o源是否可用,一方面會導致此處會不斷地在使用者態和核心態來回切換;另一方面,當i/o源長時間不可用時,就會一直占用cpu,進而不如使用阻塞i/o模型效率高。

因此,在獲知i/o源可用以後,再進行非阻塞i/o的操作是可行高效的,同時可以規避阻塞i/o導致無法執行其他程式的劣勢。

首先明確,多路i/o復用的目的:

在乙個操作中,同時監聽多個輸入輸出源,其中乙個或者多個輸入輸出源可用的時候,就會返回,也就是通知,隨後再進行讀寫操作

所以,有乙個重要的特性:通知機制,讀寫機制

先通知,再讀寫,可以較好的保證讀寫的流暢性,大部分的阻塞i/o操作不會因為輸入輸出源不可用而導致的阻塞。

之所以使用多路i/o復用,其關鍵就在於使用乙個epoll_wait()就可以監聽多個事件。但是,現實情況下是:我雖然要監聽多個事件,我是要讀,但是是不是要全讀?

對於水平觸發模式而言,不管你是不是全讀,只要你監聽的某乙個檔案描述符可用,就會通知。

這就會導致乙個問題:客戶端在一次write中向套接字寫了很多資料,而服務端只想讀緩衝區的一部分,比如頭資訊(前x個位元組),進而再選擇是否繼續讀。

如果不想讀了,套接字的緩衝區依然有資料,水平觸發模式會導致epoll_wait()還是會通知你,讀緩衝區有資料,可讀。

要知道,呼叫epoll_wait()進入核心區,如果事件可用,核心就會封裝對這個事件的響應。如果上述所說的情況大量存在,就會急劇增加核心的工作量,這是水平觸發導致核心開銷過大的重要原因。

而對於邊緣觸發,可以給予基於檔案描述符的通知機制以很強的靈活性,以讀事件為例

有些檔案描述符,要全讀,則用非阻塞i/o的方式迴圈讀出即可。

有些檔案描述符,要部分讀,那麼下次使用epoll_wait()如果沒有新資料到來,則不會通知。

至此,具體描述了水平觸發和邊沿觸發的優缺點,以及邊沿觸發配合非阻塞i/o的原因。

epoll 水平觸發與邊緣觸發

epoll也是實現i o多路復用的一種方法,為了深入了解epoll的原理,我們先來看下epoll水平觸發 level trigger,lt,lt為epoll的預設工作模式 與邊緣觸發 edge trigger,et 兩種工作模式。使用脈衝訊號來解釋lt和et可能更加貼切。level是指訊號只需要處於...

epoll 水平觸發 邊緣觸發

水平觸發 只要緩衝區還有資料,核心就還會通知使用者。使用者如果第一次讀取資料沒讀完,即使沒有任何新的操作觸發,還是可以繼續通過epoll wait來獲取事件 邊緣觸發 只有當新事件觸發的時候,才能通過epoll wait來獲取資料,如果第一次讀取資料沒讀完,就只能等待下一次事件觸發來獲取餘下的資料。...

epoll 水平觸發 邊緣觸發

先簡單比較一下level trigger 和 edge trigger 模式的不同。讓我們換乙個角度來理解et模式,事實上,epoll的et模式其實就是socket io完全狀態機。當socket由不可讀變成可讀時,epoll的et模式返回read 事件。對於read 事件,開發者需要保證把讀取緩衝...