c - Kqueue(边缘触发): Does a short read mean that read-readiness was lost?

标签 c macos freebsd epoll kqueue

在边沿触发模式 (EPOLLET) 下使用 Linux epoll 时,读/写失败并显示 EAGAIN/EWOULDBLOCK ,这意味着读/写准备丢失,并且保证通过 epoll_wait() 提供新的准备事件。一旦准备就绪。

此外,在边缘触发模式下使用 Linux epoll 和非阻塞流模式套接字时,前提是我们对 EPOLLRDHUP 感兴趣事件,那是一个EPOLLRDHUP尚未收到事件,一个简短的读/写(返回值小于请求的大小)也意味着读/写准备就绪的丢失,并且我们仍然可以在重新准备就绪时依赖新的就绪通知,即使没有读/写曾因 EAGAIN 失败过/EWOULDBLOCK .

类似地,当在边沿触发模式 (EV_CLEAR) 中使用 Kqueue (macOS/FreeBSD) 时,读/写失败并显示 EAGAIN/EWOULDBLOCK ,这意味着读/写准备丢失,并且保证通过 kevent() 提供新的准备事件。一旦准备就绪。

问题:在边沿触发模式下使用 Kqueue 和非阻塞流模式套接字时,前提是我们对 EV_EOF 感兴趣事件,那是一个EV_EOF尚未收到事件,是否有类似的保证,即短暂的读/写意味着失去读/写就绪状态,并且保证在恢复就绪状态时产生新的就绪事件?

编辑:注意:知道短阅读意味着阅读准备就绪的损失让我(在一般情况下)避免冗余调用 read()只是为了得到 EAGAIN/EWOULDBLOCK失败。

Linux epoll 上下文中短读/写的含义,来自 epoll 中的评论(7) 手册页:

For stream-oriented files (e.g., pipe, FIFO, stream socket), the condition that the read/write I/O space is exhausted can also be detected by checking the amount of data read from / written to the target file descriptor. For example, if you call read(2) by asking to read a certain amount of data and read(2) returns a lower number of bytes, you can be sure of having exhausted the read I/O space for the file descriptor. The same is true when writing using write(2). (Avoid this latter technique if you cannot guarantee that the monitored file descriptor always refers to a stream-oriented file.)

最佳答案

您询问“Kqueue in edge-triggered mode”,但 kqueue 文档不使用该术语。我想你一定是说你已经为有问题的事件启用了 EV_CLEAR 标志,其效果是

After the event is retrieved by the user, its state is reset.

( BSD documentation for kqueue() )

此外,你规定程序有

registered interest in EV_EOF events, and that an EV_EOF event was not already received

但是 EV_EOF 本身并不是一个事件;相反,它是一些可用过滤器将在适当时设置的标志,尤其是 EVFILT_READ

不管怎样,你问题的核心是

is there a similar guarantee, that a short read/write means loss of read/write-readiness, and that a new readiness event is guaranteed to be produced when readiness is regained?

据我所知,无论是 BSD 还是 Linux,都不能保证短读取表示读取准备就绪丢失。事实上,read(2) 的 Linux 文档特别指出收到信号作为短读的可能替代原因。

此外,Linux epoll() 文档为边缘触发模式下的非阻塞文件描述符推荐的使用模型是重复读取,直到读取失败并返回 EAGAIN ,使用 that 作为在文件结束之前失去准备状态的指示。我建议对具有 EV_CLEAR 生效的事件遵循与 kqueue 系统相同的策略。

我知道您希望通过在短暂读取时停止来节省一次 read() 调用,但我认为这会带来真正的风险,即让传入数据流无限期得不到服务。此外,除非您确定这些额外的读取是导致可测量的、 Not Acceptable 性能消耗的原因,否则您的担心还为时过早。

关于c - Kqueue(边缘触发): Does a short read mean that read-readiness was lost?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40123626/

相关文章:

c - 为什么我在使用双指针作为二维数组的参数时得到 'segmentation error'?

c++ - 如何将 WriteConsoleInput 写入等待 ReadConsoleInput 的子应用程序?

objective-c - 通过鼠标事件绘制到 NSView 中

c++ - 在 OSX 上构建巨大的 C++ 源代码时出现 LLVM Clang 6.0 fatal error

将 ifaddr 的地址复制到 ifreq 结构

c - emacs C 和 C++

macos - mojave 不提示用户访问联系人

postgresql - 如何在 Freebsd 上从源代码安装 PGlogical?

opencart - fatal error : Call to undefined function session_id() when installing

c - 在 Linux 上处理用户输入