gpt4 book ai didi

python - 非阻塞套接字能否从读取器/写入器引发 BlockingIOError?

转载 作者:太空宇宙 更新时间:2023-11-04 10:01:46 30 4
gpt4 key购买 nike

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 能否从编写器中引发 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)

我已经尝试发送/接收相当多的数据,但到目前为止从未发生过。从逻辑上讲,它永远不会真正发生吗?如果可以,在什么情况下会发生?

最佳答案

Can [BlockingIOError in an asyncio reader] never actually happen, logically? If if it can happen, under what circumstances?

这个问题的答案几乎肯定是系统相关的。 Python 本身不对此事提供任何保证:像 os.readsocket.recv 这样的函数只是检查底层系统调用返回的值,如果它指示一个错误,继续将系统提供的错误转换为 Python 异常。

所以问题归结为从套接字读取是否会失败并返回 EAGAIN 或如果前面的轮询/选择表明它是可读的(以及写入的等效项)。虽然这听起来确实是一种异常情况,但 select(2) man page 明确在 BUGS 下警告它:

Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination has wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block.

对于非阻塞套接字,应该将“尽管随后的读取 block ”读作“尽管随后的读取因 EAGAIN 而失败”,并且警告适用于此问题。该问题也不特定于 select()poll(2) man page还在其 BUGS 部分中提到了虚假唤醒,有关详细信息,请参阅 select(2) 手册。

换句话说,可移植代码不应依赖于从不引发 BlockingIOError 的“可读”套接字读取。 Asyncio 不依赖于它:它仅通过 not completing the futureEAGAIN 使用react,从而重新挂起等待读取的协程。

关于python - 非阻塞套接字能否从读取器/写入器引发 BlockingIOError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55625684/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com