2017-08-31 51 views
1

假設我的過程中使用的epoll有邊沿觸發,下面 情形發生:帶邊緣觸發器比賽的EPOLLLET可以嗎?

  1. 調用epoll_wait,成功與一個FD準備好讀。
  2. 同時的recv()成功,請繼續閱讀在現在
  3. 轉到步驟#1

將epoll_wait()立即返回所有數據

  • 的recv()的返回EWOULDBLOCK
  • 更多的數據來?或等到下一個數據傳入?

  • 回答

    1

    它會立即返回。

    不幸的是,邊緣觸發模式沒有很好的描述(在任何情況下,一般人都不能理解它,並且不能做出錯誤的假設,無論如何,在我看來)。

    它是什麼,它會產生什麼時候的描述符的狀態更改爲「準備就緒」(或者,不管你等待)一個事件,這意味着epoll_wait()將返回一次。然而,這不是故事的結尾。

    然後,一旦狀態翻轉到「未準備好」並返回,它就會生成下一個事件。這一點非常重要。單獨進來的數據通常不足(儘管根據文檔可能是,並且輸入數據可能產生多於一個事件......)。

    對於像套接字或管道或如此,細微之處並不重要,因爲你要去反正讀取數據什麼。這也有點顯而易見,如果你仔細想想,它也是非常有意義的。

    例如當您的描述符是eventfd時,重點在於翻轉一次到false並返回到true。有一個假設,只要你需要喚醒一個服務員,你就可以發信號通知eventfd(並且它不會多次喚醒一個等待線程,這很好)。當然,這就是它的方式,沒有什麼不同。沒人在乎你要麼貼,呵呵......它只能存儲其中一個被覆蓋值的價值,我可以不關心閱讀它。

    那麼,這是不是事情是如何工作的,因爲我發現了困難的方式。醒來一次後,您需要實際讀取描述符以在再次等待之前將狀態翻轉爲「未準備好」。否則,令人驚訝的是,自從你上次醒來以來發生的另一件事情是無關緊要的。
    再一次,如果你考慮一下,這甚至是有道理的。它可能不是你所期望的。

    你的程序寫入的方式,它會正常工作。但是,請注意,只給定一個描述符,只是阻止更有效。

    1

    這在epoll(7) manual page實際上回答了(參見「電平觸發和邊沿觸發」)。

    什麼手冊說的是,它應該工作正常,因爲EPOLLET事件由變化觸發而這種改變在你的腳步發生4

    手冊頁甚至說,解決問題的方法使用EPOLLET

    1. 與非阻塞文件描述符;並且

    2. 只能在read(2)write(2)返回EAGAIN之後等待事件。

    這是你已經在做(即使你使用等效EWOULDBLOCK,而不是EAGAIN)。

    簡而言之:當您迭代回第1步時,epoll_wait應立即返回。

    相關問題