「重磅」linux epoll 让你更好使用epoll「深入灵魂问题」

「重磅」linux epoll 让你更好使用epoll「深入灵魂问题」

1. epoll中管理注册文件描述符列表的key是什么格式?

key是通过文件描述符(比如1,2,3)以及打开的文件句柄(open file handle)组合成的。

️2. 如果将同一个文件描述符重复add(注册)到epoll 会发生什么?

调用epoll_ctl 会得到EEXIST错误码。但是如果你添加的是通过dup、dup2、fcntl(F_DUPFD)复制得到的文件描述符,这个是允许的。一般后面这种操作是用于过滤不同的事件。

️3. 如果将文件描述符添注册两个不同的epoll 实例,在该句柄上触发的事件是否都会上报给这两个epoll 实例?

答案是肯定的,但是需要区别(通过fork 继承的epoll实例,fork继承的epoll实例系统只会唤醒启动一个)

️4. 关闭一个文件描述符,会自动从所有epoll实例的注册列表中删除吗?

会的,但是必须与该描述符相关联的都需要关闭才可以(包括dup、dup2、fcntl、fork复制的描述符)

️5. 是否可以将epoll的文件描述符注册到自身的epoll实例中?

epll_ctl 将会返回错误(EINVAL),但是你可以将该epoll 描述符添加到另外一个epoll实例

️6. epoll文件描述符是否支持poll、epoll、select?

可以的,如果该描述符有需要处理的事件,那么将会触发可读事件(readable)

️7. 能否通过UNIX domain socket将epoll实例的文件描述符(注意是实例本身不是注册的文件句柄)发送给另外一个进程?

可以的,但是这样做没有任何意义,因为接受进程没有对应的注册文件列表。

️8.如果在调用epoll_wait时有多个事件触发,它们是分开返回还是一起返回?

一起返回

️9.在边缘模式(EPOLLET)模式下,是否有必要一直read/write直到errno=EAGAIN?

当你同epoll_wait收到事件时,表示这些文件描述符上的I/O请求已经准备好了,你必须要read/write直到EAGAIN。

对于一些packet/toke-oriented的文件描述符(eg:datagram socket,terminal in canonical mode),这也是惟一能够判断是否把I/O空间内容读完(写完)的方式。

对于一些流式的文件描述符(eg:pipe、FIFO、stream sock)建议也是通过这种方式,如果通过read(2)返回的读到的字节与给定的buffer大小比较来判断是否已经读完(ret_byte < buffer_size),很有可能会读取不到后面的FIN包

️10.对文件描述符的操作是否会对一些已经到达但是还未触发的事件(epoll_wait)产生影响?

对文件描述符的flag做remove操作,将不会产生什么影响。但是如果对其做EPOLL_CTL_MOD将会重新获取到有效的I/O事件(epoll_wait).比如:ET模式第一次没有将缓冲区数据读完,正常情况下余下部分的数据将不会及时读取到,但是如果此时你对文件描述符做一个MOD操作那么epoll_wait又将返回该可读事件。


分享到:


相關文章: