男人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?

更新: 又发现一件事:男人epoll_wait:

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

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

有帮助吗?

解决方案

如果 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;
       }
   }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top