c – 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事件,是否有类似的保证,即短读/ write意味着读/写就绪的丢失,并且在重新获得准备就绪时保证会产生新的准备事件? 编辑:注意:知道短读取意味着读取就绪性的丢失允许我(在一般情况下)避免冗余调用read()只是为了获得EAGAIN / EWOULDBLOCK失败. Linux epoll上下文中的简短读/写的含义,请参见epoll(7)手册页中的注释:
解决方法
您询问“边缘触发模式下的Kqueue”,但kqueue文档不使用该术语.我认为你必须意味着你已经为相关事件启用了EV_CLEAR标志,效果如此
(BSD documentation for 此外,您规定该程序具有
但EV_EOF本身并不是一个事件;相反,它是一个标志,一些可用的过滤器将在适当时设置,尤其是EVFILT_READ. 无论如何,你问题的核心是
据我所知,无法保证短读取信号会导致读取准备就绪,无论是BSD还是Linux.实际上,用于读取(2)的Linux文档特别指出接收信号是短读取的可能替代原因. 此外,Linux epoll()文档推荐用于边缘触发模式下的非阻塞文件描述符的使用模型是重复读取,直到读取因EAGAIN而失败,使用它作为文件结束前失去准备状态的指示.对于EV_CLEAR生效的事件,我建议对kqueue系统遵循相同的策略. 我认识到你希望通过停止一次简短的读取来保存一个read()调用,但我认为这给了一个真正的风险,这个过程最少留下无法保留的传入数据流.此外,除非您确定这些额外的读取是造成可衡量的,不可接受的性能损失的原因,否则您的担忧还为时过早. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |