Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Kqueue(边缘触发):短读是否意味着读准备就绪已丢失?_C_Macos_Freebsd_Epoll_Kqueue - Fatal编程技术网

C Kqueue(边缘触发):短读是否意味着读准备就绪已丢失?

C Kqueue(边缘触发):短读是否意味着读准备就绪已丢失?,c,macos,freebsd,epoll,kqueue,C,Macos,Freebsd,Epoll,Kqueue,在边缘触发模式(EPOLLET)下使用Linux epoll时,如果使用EAGAIN/ewoldblock,读/写操作失败,则意味着读/写准备就绪已丢失,一旦恢复准备就绪,将通过epoll\u wait()确保新的准备就绪事件可用 此外,在边缘触发模式下使用Linux epoll和非阻塞流模式套接字时,如果我们对EPOLLRDHUP事件感兴趣,并且尚未收到EPOLLRDHUP事件,则会发生短读/写(返回值小于请求的大小)也意味着读/写准备就绪的丢失,当准备就绪恢复时,我们仍然可以依赖新的准备就绪

在边缘触发模式(
EPOLLET
)下使用Linux epoll时,如果使用
EAGAIN
/
ewoldblock
,读/写操作失败,则意味着读/写准备就绪已丢失,一旦恢复准备就绪,将通过
epoll\u wait()
确保新的准备就绪事件可用

此外,在边缘触发模式下使用Linux epoll和非阻塞流模式套接字时,如果我们对
EPOLLRDHUP
事件感兴趣,并且尚未收到
EPOLLRDHUP
事件,则会发生短读/写(返回值小于请求的大小)也意味着读/写准备就绪的丢失,当准备就绪恢复时,我们仍然可以依赖新的准备就绪通知,即使在
EAGAIN
/
EWOULDBLOCK
中没有读/写失败

类似地,在边缘触发模式(
EV_CLEAR
)下使用Kqueue(macOS/FreeBSD)时,如果使用
EAGAIN
/
EWOULDBLOCK
),读/写失败,则意味着读/写准备就绪已丢失,并且通过
kevent()保证提供新的准备就绪事件
一旦恢复准备状态

问题:在边缘触发模式下使用Kqueue和非阻塞流模式套接字时,如果我们对
EV_EOF
事件感兴趣,并且尚未收到
EV_EOF
事件,是否有类似的保证,短读/写意味着读/写准备就绪的丢失,并且保证在恢复准备就绪时生成新的准备就绪事件

编辑:注意:知道短读意味着失去读准备,我(在一般情况下)可以避免重复调用
read()
,只是为了获得
EAGAIN
/
EWOULDBLOCK
故障

在Linux e波尔环境中,短读/写的含义如下所示,参见
e波尔
(7)手册页中的注释:

对于面向流的文件(例如,管道、FIFO、流套接字),读/写I/O空间耗尽的情况也可以通过检查从目标文件描述符读取/写入的数据量来检测。例如,如果您通过请求读取一定数量的数据来调用read(2),并且read(2)返回的字节数较低,那么您可以确定已经耗尽了文件描述符的读取I/O空间。使用write(2)进行写入时也是如此。(如果无法保证受监视的文件描述符始终引用面向流的文件,请避免使用后一种技术。)

您询问“边缘触发模式下的Kqueue”,但Kqueue文档未使用该术语。我想您一定是说您已经为相关事件启用了
EV_CLEAR
标志,其效果是

用户检索事件后,其状态将重置

()

此外,您规定该程序具有

已登记对
EV_EOF
事件感兴趣,且尚未收到
EV_EOF
事件

但是,EV_EOF本身并不是一个事件;相反,它是一个标志,一些可用的过滤器将在适当时设置,特别是
EVFILT\u READ

无论如何,你问题的核心是

是否有类似的保证,即短读/写意味着读/写准备就绪丢失,并且保证在恢复准备就绪时生成新的准备就绪事件

就我所能确定的,无论是对于BSD还是对于Linux,都不能保证短读意味着读准备就绪的丢失。事实上,
read(2)
的Linux文档专门调用接收信号作为短读的可能替代原因

此外,Linux
epoll()
文档建议在边缘触发模式下使用非阻塞文件描述符的使用模型是重复读取,直到使用
EAGAIN
读取失败,并将此作为文件结束前准备就绪丢失的指示。对于
EV\u CLEAR
生效的事件,我建议对kqueue系统遵循相同的策略


我知道您希望通过在短时间读取时停止来保存一个
read()
调用,但我认为这会带来真正的过程风险,至少不会让传入的数据流无限期地不被服务。此外,除非您已经确定这些额外读取导致了可测量的、不可接受的性能损耗,否则您的担心还为时过早。

请注意,在这个问题中,我假设使用非阻塞模式套接字,因此不会发生因信号中断而导致的短读取,至少在Linux上不会,我一般认为,在任何类似POSIX的系统上,Linux上的短读/写都意味着“读准备就绪的丧失”,至少从epoll的角度来看是这样的。epoll手册页(我在问题中引用的部分)中明确说明了这一点。注意,我排除了
EV_EOF
事件(设置了该标志的事件)挂起或已被接收的情况,因为在这种情况下,短读总是由输入结束而不是读取准备就绪丢失引起的。与Linux e波尔的
EPOLLRDHUP
类似。