1.如何分辨epoll集中的文件描述符

关键是文件描述符编号和打开文件的描述(也称为“打开文件句柄”,内核的内部表示)的组合
打开的文件)。

2.如果在epoll实例上注册了两次相同的文件描述符,会发生什么情况?

可能会获得EEXIST
但是,可以向同一个epoll实例添加一个重复的(dup(2)、dup2(2)、fcntl(2) F_DUPFD)文件描述符。
如果用不同的事件掩码(events)注册了重复的文件描述符,那么这对于过滤事件是一种有用的技术。

3.两个epoll实例可以等待相同的文件描述符吗?如果是,是否向两个epoll文件描述符报告事件?

是的,事情会向双方报告。然而,要正确地做到这一点,可能需要仔细的编程。

4.epoll文件描述符本身是poll/epoll/selectable?

是的。如果epoll文件描述符有事件在等待,那么它将表明是可读的。

5.如果试图将epoll文件(efd)描述符放入其自己的文件描述符集,会发生什么情况

epoll_ctl调用失败(返回EINVAL).
但是,您可以在另一个epoll文件描述符集中添加epoll文件描述符。

6. 我可以通过UNIX域套接字向另一个进程发送epoll文件描述符吗

是的,但是这样做没有意义,因为接收进程在epoll集合中没有文件描述符的副本。

7.关闭文件描述符会导致它从所有epoll集自动删除吗?

  1. 是的,但要注意以下一点。
  • 文件描述符是对打开的文件描述的引用(参见open(2))。
  • 当一个文件描述符通过dup(2)、dup2(2)、fcntl(2)、F_DUPFD或fork(2)被复制时,一个指向同一个打开的文件描述符的新文件描述符就会被创建
  • 打开的文件描述将继续存在,直到所有引用它的文件描述符都已关闭。
  • 只有在所有引用底层打开文件描述的文件描述符都已关闭之后(或者在使用epoll_ctl(2) EPOLL_CTL_DEL显式删除文件描述符之前),才会从epoll集合中删除文件描述符。
  • 即使在关闭了属于epoll集的文件描述符之后,如果引用相同底层文件描述符的其他文件描述符仍然打开,也可能报告该文件描述符的事件。

    8.如果epoll_wait(2)调用之间发生多个事件,它们是合并还是单独报告?

    合并!

9.文件描述符上的操作是否会影响已经收集但尚未报告的事件?

可以对现有的文件描述符执行两项操作。Remove在这种情况下是没有意义的。修改后将重新读取可用的I/O。

10.当使用EPOLLET标志(边缘触发行为)时,我需要持续读/写文件描述符直到EAGAIN吗?

从epoll_wait(2)接收事件将提示您,该文件描述符已经为请求的I/O操作准备好了。您必须认为它已经准备好了,直到下一次(非阻塞)读/写产生EAGAIN。何时以及如何使用文件描述符完全取决于您。
对于packet/token-oriented files (例如,数据报套接字,规范模式下的终端),检测读/写I/O空间结束的唯一方法是继续读/写直到EAGAIN。
对于 stream-oriented files (e.g., pipe, FIFO, stream socket)读写I/O空间耗尽的情况也可以通过检查从目标文件描述符读取/写入的数据量来检测。例如,如果您调用read(2)来请求读取一定数量的数据,而read(2)返回的字节数更少,那么您可以确定已经耗尽了文件描述符的读I/O空间。
使用write(2)写的时候也是如此。(如果不能保证被监视的文件描述符总是指向面向流的文件,请避免使用后一种技术。)