![](/img/trans.png)
[英]Force a non-blocking UDP socket to raise BlockingIOError on sendto
[英]Can a non-blocking socket raise BlockingIOError from a reader/writer?
sock.recvfrom
可以从读者sock.recvfrom
引发BlockingIOError
吗? 比如下面
sock.setblocking(False)
def reader()
try:
(data, addr) = sock.recvfrom(512)
except BlockingIOError:
# Can this ever be raised?
loop.add_reader(sock.fileno(), reader)
类似地, sock.send
是否可以从作者sock.send
引发BlockingIOError
?
sock.setblocking(False)
def writer()
try:
bytes_sent = sock.send(data)
except BlockingIOError:
# Can this ever be raised?
loop.add_writer(sock.fileno(), writer)
我已经尝试发送/接收相当多的数据,但到目前为止从未发生过。 从逻辑上讲,它真的永远不会发生吗? 如果可以,在什么情况下发生?
[
BlockingIOError
in a asyncio reader] 从逻辑上讲,真的永远不会发生吗? 如果可以的话,是在什么情况下发生的?
这个问题的答案几乎肯定取决于系统。 Python 本身不提供任何保证: os.read
和socket.recv
类的函数只检查底层系统调用返回的值,如果它指示错误,继续将系统提供的错误转换为蟒蛇异常。
因此,问题归结为如果前面的轮询/选择表明它是可读的(以及写入的等效项),那么从套接字读取是否会因EAGAIN
或等效项而失败。 虽然这听起来像是一种异常情况,但select(2)
手册页在 BUGS 下明确警告了它:
在 Linux 下,
select()
可能会将套接字文件描述符报告为“ready for reading”,但随后的读取会阻塞。 例如,当数据已到达但检查时校验和错误并被丢弃时,可能会发生这种情况。 可能还有其他情况,其中文件描述符被虚假地报告为就绪。 因此,在不应阻塞的套接字上使用O_NONBLOCK
可能更安全。
对于非阻塞套接字,应该将“尽管如此,随后的读取阻塞”读作“尽管如此,随后的读取失败并使用EAGAIN
”,并且警告适用于这个问题。 这个问题也不是特定于select()
; poll(2)
手册页还在其 BUGS 部分提到了虚假唤醒,有关详细信息,请参阅select(2)
手册。
换句话说,可移植代码不应依赖于从不会引发BlockingIOError
“可读”套接字读取。 Asyncio 不依赖它:它通过简单地不完成 future来对EAGAIN
做出反应,从而重新挂起等待读取的协程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.