- 1.如何分辨epoll集中的文件描述符
- 2.如果在epoll实例上注册了两次相同的文件描述符,会发生什么情况?
- 3.两个
epoll
实例可以等待相同的文件描述符吗?如果是,是否向两个epoll文件描述符报告事件? - 4.epoll文件描述符本身是poll/epoll/selectable?
- 5.如果试图将epoll文件(efd)描述符放入其自己的文件描述符集,会发生什么情况
- 6. 我可以通过UNIX域套接字向另一个进程发送
epoll
文件描述符吗 - 7.关闭文件描述符会导致它从所有
epoll
集自动删除吗? - 8.如果epoll_wait(2)调用之间发生多个事件,它们是合并还是单独报告?
- 9.文件描述符上的操作是否会影响已经收集但尚未报告的事件?
- 10.当使用EPOLLET标志(边缘触发行为)时,我需要持续读/写文件描述符直到EAGAIN吗?
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
集自动删除吗?
是的,但要注意以下一点。
- 文件描述符是对打开的文件描述的引用(参见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)写的时候也是如此。(如果不能保证被监视的文件描述符总是指向面向流的文件,请避免使用后一种技术。)