2010-10-23 55 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

相关问题