【发布时间】:2017-02-28 15:15:00
【问题描述】:
在边沿触发模式 (EPOLLET) 下使用 Linux epoll 时,读/写失败并出现EAGAIN/EWOULDBLOCK,这意味着读/写准备丢失,并且保证一旦恢复就绪状态,就会通过epoll_wait() 提供新的就绪事件。
此外,当使用 Linux epoll 在边缘触发模式和非阻塞流模式套接字时,如果我们注册了对 EPOLLRDHUP 事件的兴趣,并且 EPOLLRDHUP 事件是还没有收到,短的读/写(返回值小于请求的大小)也意味着读/写准备的丢失,当准备恢复时,我们仍然可以依赖新的准备通知,即使没有读/写失败EAGAIN/EWOULDBLOCK.
类似地,在边缘触发模式 (EV_CLEAR) 下使用 Kqueue (macOS/FreeBSD) 时,读取/写入失败并出现 EAGAIN/EWOULDBLOCK,这意味着读取/write-readiness 丢失了,一旦重新准备就绪,就可以通过kevent() 保证新的准备就绪事件可用。
问题:在边缘触发模式下使用 Kqueue 和非阻塞流模式套接字时,如果我们注册了对 EV_EOF 事件的兴趣,并且还没有收到EV_EOF 事件,是否有类似的保证,短读/写意味着读/写准备的丢失,并且在重新准备就绪时保证产生新的准备事件?
编辑: 注意:知道短读意味着失去读准备让我(在一般情况下)避免重复调用 read() 只是为了获得 EAGAIN/ EWOULDBLOCK 失败。
Linux epoll 上下文中短读/写的含义,来自epoll(7) 手册页中的这条评论:
对于面向流的文件(如管道、FIFO、流套接字),也可以通过检查目标文件读/写的数据量来检测读/写I/O空间耗尽的情况描述符。例如,如果您通过请求读取一定数量的数据来调用 read(2),而 read(2) 返回的字节数较少,则可以确定文件描述符的读取 I/O 空间已用尽。使用 write(2) 写入时也是如此。 (如果您不能保证被监控的文件描述符总是指向一个面向流的文件,请避免使用后一种技术。)
【问题讨论】:
标签: c macos freebsd epoll kqueue