Проблема связана с буферизацией. Я не смог найти какую-либо конкретную документацию, но похоже, что при первом вызове readline
.
весь ввод данных помещается в буфер.
Вы можете указать отсутствие буферизации в качестве третьей переменной в fdopen, но это не разрешено для текста, выбрасывая
ValueError: can't have unbuffered text 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'
>>>([], [], [])
Я думаю, это поведение, которое вы ожидали, и если вы затем удалите переменную отключить буферизацию 0 из вызовов fdopen
,
writeable = os.fdopen(write, "wb")
readable = os.fdopen(read, "rb")
вы вернетесь:
>>>b'first\n'
>>>([], [], [])
>>>b'second\n'
>>>([], [], [])
Как в вашем первоначальном примере.