Я боролся с написанием и чтением труб. Проблема заключалась в том, что с одной стороны я обрабатывал канал через файл-объект, полученный с помощью open()
. А с другой стороны я использовал дескриптор файла, полученный с помощью «low-level» os.open()
. Несмотря на то, что похожий код ведет себя очень по-разному, и я не очень понимаю, почему.
Я сделал маленький пример. Я изменяю метод записи в канал. В write_1.py я использую os.open()
, и все работает как положено. В write_2.py с использованием open()
, при чтении из канала я получаю EAGAIN -обнаружение и получаю значимый вывод только тогда, когда сторона записи закрыта с использованием pipe.close()
в конце .
Чтение в обоих случаях одинаково, см. read.py .
Можете ли вы объяснить другое поведение?
(Python версия 3.5.2)
Файлы
# write_1.py
import os
import errno
import time
bufferSize = 100
PATH = "pipe"
i = 0
pipe = os.open(PATH, os.O_WRONLY | os.O_NONBLOCK)
while i < 20:
i +=1
my_str = "written {0}-times".format(i)
try:
input = os.write(pipe, my_str.encode())
except OSError as err:
if err.errno == 11:
print("error 11")
continue
else:
raise err
if input:
print("written {0} chars ".format(input))
print("Sleep 500 ms")
time.sleep(0.5)
os.close(pipe)
# write_2.py
import os
import errno
import time
bufferSize = 100
PATH = "pipe"
i = 0
pipe = open(PATH, "w")
fd = pipe.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
while i < 20:
i +=1
my_str = "written {0}-times".format(i)
try:
input = pipe.write(my_str)
except OSError as err:
if err.errno == 11:
print("error 11")
continue
else:
raise err
if input:
print("written {0} chars ".format(input))
print("Sleep 500 ms")
time.sleep(0.5)
pipe.close()
# read.py
import os
import errno
import time
bufferSize = 100
PATH = "pipe"
i = 0
pipe = os.open(PATH, os.O_RDONLY | os.O_NONBLOCK)
while i < 100:
i +=1
try:
input = os.read(pipe, bufferSize)
except OSError as err:
if err.errno == 11:
print("error 11")
print("Sleep 500 ms")
time.sleep(0.5)
continue
else:
raise err
if input:
print(input)
print("Sleep 500 ms")
time.sleep(0.5)
os.close(pipe)