2010-10-23 54 views
2

人的epoll:如何使用EPOLLET使用epoll_select讀取多個文件描述符?

The suggested way to use epoll as an edge-triggered (EPOLLET) interface is as follows: 
    i with nonblocking file descriptors; and 
    ii by waiting for an event only after read(2) or write(2) return EAGAIN. 

假設我們有兩個FDS:第一是被動的,數據只能有時,第二個是活動的,數據只是有時無法使用。

epoll_wait返回,我們可以讀取兩者。我們在循環中讀取{第一個,第二個,第二個}(沒有調用epoll_wait,因爲它可能在數據仍然可用時突然阻塞)。

現在第一個文件描述符在讀取時返回EAGAIN。

怎麼辦?

  1. 如果我們繼續閱讀循環中的第二個fd(沒有調用epoll_wait),我們可能會錯過在第一個fd上可用的數據。它只會讀取和讀取和閱讀沒有EAGAIN。
  2. 如果我們將在每次從第二個fd讀取數據之前與epoll_wait進行「協商」,epoll_wait可能會突然阻塞,因爲之前的調用沒有任何變化(數據在第一個FD上仍然不可用,並且仍然在第二個FD上可用)。

如何繼續處理第二個FD,但不會忘記第一個FD?

更新:發現一件事:男人epoll_wait:

while specifying timeout equal to zero makes epoll_wait() to return immediately even if no events are available 

有了這個,我可以列舉的文件描述符事件,即使沒有活動。

回答

0

如果FD2經常可讀,您可能會認爲epoll不適合它。爲了坐下來閱讀,可能需要脫掉一個線程。

否則,在循環中讀取FD2直到它被耗盡,但在循環中嘗試每隔X次讀取一次FD1。如果FD1有數據,請閱讀它。如果沒有,您只需獲得EAGAIN,重置X計數器並返回讀取FD2。當兩者都耗盡時,你回到epoll_wait。

喜歡的東西:不是

count = 1; 

while (true) 
{ 
    read fd2; 

    if (EAGAIN) 
     break; 
    else 
     process data; 

    count--; 

    if (! count) 
    { 
     while (true) 
     { 
      read fd1; 

      if (EAGAIN) 
       count = 10; 
       break; 
      else 
       process data; 
     } 
    } 
} 
+0

OK 「嘗試讀取FD1」 我們可以調用epoll_wait零超時。但爲時已晚:我已經在沒有EPOLLET(帶EPOLLONESHOT)的情況下實現了它,並且在這裏和那裏調用了epoll_ctl。 – 2010-10-24 12:22:45

相關問題