以下最小代码的行为似乎不正确。为什么第二个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
答案 0 :(得分:1)
问题是由于缓冲引起的。我找不到任何具体的文档,但是当您第一次调用readline
时,似乎完整的输入已被拉到缓冲区中。
您可以在fdopen中将第三个变量指定为无缓冲,但不允许在文本中抛出
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'
>>>([], [], [])
与您的原始示例一样。