如何使用EPOLLET使用epoll_select读取多个文件描述符?

时间:2010-10-23 11:47:35

标签: linux epoll epollet

man epoll:

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仍然可用)。 / LI>

    如何继续处理第二个FD,但不忘记第一个FD?

    更新:发现了一件事:man epoll_wait:

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

    有了这个,我可以枚举FD的事件,即使没有事件。

1 个答案:

答案 0 :(得分: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;
       }
   }
}