假設我的過程中使用的epoll有邊沿觸發,下面 情形發生:帶邊緣觸發器比賽的EPOLLLET可以嗎?
- 調用epoll_wait,成功與一個FD準備好讀。
- 同時的recv()成功,請繼續閱讀在現在
- 轉到步驟#1
將epoll_wait()立即返回所有數據
假設我的過程中使用的epoll有邊沿觸發,下面 情形發生:帶邊緣觸發器比賽的EPOLLLET可以嗎?
將epoll_wait()立即返回所有數據
它會立即返回。
不幸的是,邊緣觸發模式沒有很好的描述(在任何情況下,一般人都不能理解它,並且不能做出錯誤的假設,無論如何,在我看來)。
它是什麼,它會產生什麼時候的描述符的狀態更改爲「準備就緒」(或者,不管你等待)一個事件,這意味着epoll_wait()
將返回一次。然而,這不是故事的結尾。
然後,一旦狀態翻轉到「未準備好」並返回,它就會生成下一個事件。這一點非常重要。單獨進來的數據通常不足(儘管根據文檔可能是,並且輸入數據可能產生多於一個事件......)。
對於像套接字或管道或如此,細微之處並不重要,因爲你要去反正讀取數據什麼。這也有點顯而易見,如果你仔細想想,它也是非常有意義的。
例如當您的描述符是eventfd
時,重點在於翻轉一次到false
並返回到true
。有一個假設,只要你需要喚醒一個服務員,你就可以發信號通知eventfd(並且它不會多次喚醒一個等待線程,這很好)。當然,這就是它的方式,沒有什麼不同。沒人在乎你要麼貼,呵呵......它只能存儲其中一個被覆蓋值的價值,我可以不關心閱讀它。
那麼,這是不是事情是如何工作的,因爲我發現了困難的方式。醒來一次後,您需要實際讀取描述符以在再次等待之前將狀態翻轉爲「未準備好」。否則,令人驚訝的是,自從你上次醒來以來發生的另一件事情是無關緊要的。
再一次,如果你考慮一下,這甚至是有道理的。它可能不是你所期望的。
你的程序寫入的方式,它會正常工作。但是,請注意,只給定一個描述符,只是阻止更有效。
這在epoll(7)
manual page實際上回答了(參見「電平觸發和邊沿觸發」)。
什麼手冊說的是,它應該工作正常,因爲EPOLLET
事件由變化觸發而這種改變在你的腳步發生4
手冊頁甚至說,解決問題的方法使用EPOLLET
是
與非阻塞文件描述符;並且
只能在
read(2)
或write(2)
返回EAGAIN
之後等待事件。
這是你已經在做(即使你使用等效EWOULDBLOCK
,而不是EAGAIN
)。
簡而言之:當您迭代回第1步時,epoll_wait
應立即返回。