在非阻塞流模式套接字(read()
)上考虑以下SOCK_STREAM
调用:
ssize_t n = read(socket_fd, buffer, size);
假设远程对等体不会关闭连接,并且不会关闭其写入的一半连接(从本地角度来看,读取一半)。
在Linux上,在这些情况下进行简短读取(n > 0 && n < size
)意味着内核级读取缓冲区已用尽,并且立即后续调用通常会因EAGAIN
/ {{而失败1}}(除非新数据设法在两次调用之间到达,否则它将失败)。
换句话说,在Linux上,如果EWOULDBLOCK
足够大,read()
的调用将始终消耗所有可立即使用的内容。
同样对于size
,在Linux上,短写总是意味着内核级缓冲区被填充,并且立即后续调用可能会因write()
/ EAGAIN
而失败
问题1:macOS / OSX上是否也保证了这一点?
问题2:这在FreeBSD上也有保证吗?
问题3:这是否需要/由POSIX保证?
我知道这在Linux上是正确的,因为EWOULDBLOCK
的手册页中有以下注释(第7节):
编辑:作为问题的动机,考虑一种情况,你想同时处理多个套接字上的输入,无论出于何种原因,你想通过依次完全耗尽每个套接字的内核缓冲区来做到这一点(即“深度优先”而不是“广度优先”)。显然可以通过在就绪就绪套接字上重复读取直到它以对于面向流的文件(例如,管道,FIFO,流套接字),还可以通过检查从目标文件读取/写入的数据量来检测读/写I / O空间耗尽的情况。描述。例如,如果通过要求读取一定量的数据来调用read(2)并且read(2)返回较少的字节数,则可以确保已经耗尽了文件描述符的读取I / O空间。使用write(2)写入时也是如此。 (如果您不能保证受监视的文件描述符始终引用面向流的文件,请避免使用后一种技术。)
epoll
/ EAGAIN
失败来完成,但如果前一次读取很短,则最后一次调用将是多余的,并且我们知道简短的阅读是对疲惫的保证。
答案 0 :(得分:1)