为什么 select.select 告诉我它不可读
Why is select.select telling me it is not readable
以下最小代码的行为似乎不正确。为什么第二个 select.select 找不到剩余的行。某处是否有缓冲以及如何公开正确的缓冲区?
import select
import os
read, write = os.pipe()
writeable = os.fdopen(write, "w")
readable = os.fdopen(read, "r")
writeable.write("first\n")
writeable.write("second\n")
writeable.flush()
if select.select([readable], [], [], 10)[0][0] == readable:
print(readable.readline())
print(str(select.select([readable], [], [], 1)))
print(readable.readline())
--- 结果:
first
([], [], [])
second
问题是由于缓冲。我找不到任何具体的文档,但当您第一次调用 readline
.
时,看起来完整的输入已被拉入缓冲区
您可以指定无缓冲作为 fdopen 中的第三个变量,但不允许用于文本,throwing
ValueError: can't have unbuffered text I/O
如果您将输入设为允许无缓冲 I/O 的字节流,您可以看到差异(更改标记有注释):
import select
import os
read, write = os.pipe()
# Use a byte stream and add 0 to disable buffering
writeable = os.fdopen(write, "wb", 0)
readable = os.fdopen(read, "rb", 0)
# Write in bytes
writeable.write(b"first\n")
writeable.write(b"second\n")
writeable.flush()
if select.select([readable], [], [], 10)[0][0] == readable:
print(readable.readline())
print(str(select.select([readable], [], [], 1)))
print(readable.readline())
# Do another check on select.
print(str(select.select([readable], [], [], 1)))
这样做会给我们一个输出:
>>>b'first\n'
>>>([<_io.FileIO name=4 mode='rb' closefd=True>], [], [])
>>>b'second\n'
>>>([], [], [])
我猜这就是您所期望的行为,如果您随后从 fdopen
调用中删除禁用缓冲 0 变量,
writeable = os.fdopen(write, "wb")
readable = os.fdopen(read, "rb")
你回来了:
>>>b'first\n'
>>>([], [], [])
>>>b'second\n'
>>>([], [], [])
与您原来的示例一样。
以下最小代码的行为似乎不正确。为什么第二个 select.select 找不到剩余的行。某处是否有缓冲以及如何公开正确的缓冲区?
import select
import os
read, write = os.pipe()
writeable = os.fdopen(write, "w")
readable = os.fdopen(read, "r")
writeable.write("first\n")
writeable.write("second\n")
writeable.flush()
if select.select([readable], [], [], 10)[0][0] == readable:
print(readable.readline())
print(str(select.select([readable], [], [], 1)))
print(readable.readline())
--- 结果:
first
([], [], [])
second
问题是由于缓冲。我找不到任何具体的文档,但当您第一次调用 readline
.
您可以指定无缓冲作为 fdopen 中的第三个变量,但不允许用于文本,throwing
ValueError: can't have unbuffered text I/O
如果您将输入设为允许无缓冲 I/O 的字节流,您可以看到差异(更改标记有注释):
import select
import os
read, write = os.pipe()
# Use a byte stream and add 0 to disable buffering
writeable = os.fdopen(write, "wb", 0)
readable = os.fdopen(read, "rb", 0)
# Write in bytes
writeable.write(b"first\n")
writeable.write(b"second\n")
writeable.flush()
if select.select([readable], [], [], 10)[0][0] == readable:
print(readable.readline())
print(str(select.select([readable], [], [], 1)))
print(readable.readline())
# Do another check on select.
print(str(select.select([readable], [], [], 1)))
这样做会给我们一个输出:
>>>b'first\n'
>>>([<_io.FileIO name=4 mode='rb' closefd=True>], [], [])
>>>b'second\n'
>>>([], [], [])
我猜这就是您所期望的行为,如果您随后从 fdopen
调用中删除禁用缓冲 0 变量,
writeable = os.fdopen(write, "wb")
readable = os.fdopen(read, "rb")
你回来了:
>>>b'first\n'
>>>([], [], [])
>>>b'second\n'
>>>([], [], [])
与您原来的示例一样。