代码之家  ›  专栏  ›  技术社区  ›  Vi.

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

  •  2
  • Vi.  · 技术社区  · 14 年前

    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上的数据已经可用。它只会读,读,读,没有伊根。
    2. 如果在每次从第二个fd读取数据之前,我们将与epoll_wait“协商”,epoll_wait可能会突然阻塞,因为与前一个调用没有任何变化(数据在第一个fd上仍然不可用,在第二个fd上仍然可用)。

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

    更新: 又发现了一件事:等一下:

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

    1 回复  |  直到 14 年前
        1
  •  0
  •   Duck    14 年前

    如果FD2是持续可读的,您可能会认为epoll不适合它。坐下来读一读也许值得一读。

    否则,在循环中读取FD2,直到它被排出,但在循环中,它尝试每X次读取一次FD1。如果FD1有数据,读取它。如果没有,你只需要得到伊根,重置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;
           }
       }
    }
    
    推荐文章