3

人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.

想象一下我们有两个 fd:第一个是被动的,数据仅有时可用,第二个是主动的,数据有时不可用。

epoll_wait 返回我们可以读取两者。我们在循环中读取{第一个,而不是第二个}(没有调用 epoll_wait 因为它可能会在数据仍然可用时突然阻塞)。

现在第一个文件描述符在读取时返回 EAGAIN。

该怎么办?

  1. 如果我们继续在循环中读取第二个 fd(不调用 epoll_wait),我们可能会错过第一个 fd 上的数据可用。它只会在没有 EAGAIN 的情况下阅读和阅读。
  2. 如果我们在每次从第二个 fd 读取之前“咨询” epoll_wait,则 epoll_wait 可能会因为前一次调用没有任何更改而突然阻塞(数据在第一个 FD 上仍然不可用,但在第二个 FD 上仍然可用)。

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

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

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

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

4

1 回答 1

1

如果 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;
       }
   }
}
于 2010-10-24T04:44:42.373 回答