epoll 水平觸發與邊緣觸發

2022-08-28 18:33:08 字數 1987 閱讀 4756

epoll也是實現i/o多路復用的一種方法,為了深入了解epoll的原理,我們先來看下epoll水平觸發(level trigger,lt,lt為epoll的預設工作模式)與邊緣觸發(edge trigger,et)兩種工作模式。

使用脈衝訊號來解釋lt和et可能更加貼切。level是指訊號只需要處於水平,就一直會觸發;而edge則是指訊號為上公升沿或者下降沿時觸發。說得還有點玄乎,我們以生活中的乙個例子來模擬lt和et是如何確定讀操作是否就緒的。

只要緩衝內容不為空,lt模式返回讀就緒。

只要緩衝區還不滿,lt模式會返回寫就緒。

(1)當緩衝區由不可讀變為可讀的時候,即緩衝區由空變為不空的時候。

(2)當有新資料到達時,即緩衝區中的待讀資料變多的時候。

(3)當緩衝區有資料可讀,且應用程序對相應的描述符進行epoll_ctl_mod 修改epollin事件時。

(1)當緩衝區由不可寫變為可寫時。

(2)當有舊資料被傳送走,即緩衝區中的內容變少的時候。

(3)當緩衝區有空間可寫,且應用程序對相應的描述符進行epoll_ctl_mod 修改epollout事件時。

實驗1對標準輸入檔案描述符使用et模式進行監聽。當我們輸入一組字元並接下回車時,螢幕中會輸出」hello world」。但是沒有呼叫read函式將快取區的資料取出來, 緩衝區的資料還是留在那。

1 #include 2 #include 3 #include 4

5int

main()620

}21}22 }

輸出:

$ ./epoll1

ahello world

abchello world

hello

hello world

ttthello world

當使用者輸入一組字元,這組字元被送入緩衝區,因為緩衝區由空變成不空,所以et返回讀就緒,輸出」hello world」。

之後再次執行epoll_wait,但et模式下只會通知應用程序一次,故導致epoll_wait阻塞。

如果使用者再次輸入一組字元,導致緩衝區內容增多,et會再返回就緒,應用程序再次輸出」hello world」。

如果將上面的**中的event.events = epollin | epollet;改成event.events = epollin;,即使用lt模式,則執行程式後,會一直輸出hello world。

實驗2對標準輸入檔案描述符使用lt模式進行監聽。當我們輸入一組字元並接下回車時,螢幕中會輸出」hello world」。

1 #include 2 #include 3 #include 4

5int

main()622

}23}24 }

輸出:

$ ./epoll2

abchello world

eeeee

hello world

lihao

hello world

實驗2中使用的是lt模式,則每次epoll_wait返回時我們都將緩衝區的資料讀完,下次再呼叫epoll_wait時就會阻塞,直到下次再輸入字元。

如果將上面的程式改為每次唯讀乙個字元,那麼每次輸入多少個字元,則會在螢幕中輸出多少個「hello world」。有意思吧。

實驗3對標準輸入檔案描述符使用et模式進行監聽。當我們輸入任何輸入並接下回車時,螢幕中會死迴圈輸出」hello world」。

1 #include 2 #include 3 #include 4

5int

main()623

}24}25 }

實驗3使用et模式,但是每次讀就緒後都主動對描述符進行epoll_ctl_mod 修改epollin事件,由上面的描述我們可以知道,會再次觸發讀就緒,這樣就導致程式出現死迴圈,不斷地在螢幕中輸出」hello world」。但是,如果我們將epoll_ctl_mod 改為epoll_ctl_add,則程式的執行將不會出現死迴圈的情況。

epoll 水平觸發 邊緣觸發

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

epoll 水平觸發 邊緣觸發

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

epoll的水平觸發和邊緣觸發

即level triggered and edge triggered 簡單說來 level triggered 只要事件是處於就緒狀態,你每詢問一次,就告訴你一次它處於就緒狀態。edge triggered 只有在狀態改變的時候告訴你,這也是為什麼et模式下,建議用非阻塞的socket。下面我們來...