Поведение open () и os.open () при использовании каналов - PullRequest
1 голос
/ 02 мая 2019

Я боролся с написанием и чтением труб. Проблема заключалась в том, что с одной стороны я обрабатывал канал через файл-объект, полученный с помощью 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)

1 Ответ

2 голосов
/ 02 мая 2019

С open вы приняли настройку буферизации по умолчанию (не предоставляя аргумент buffering), поэтому вы получаете объект буферизованного файла.Этот буфер отделен от любой буферизации на уровне ОС.

При os.open отсутствует файловый объект и буферизация на уровне файлового объекта.

(Кроме того, вы открыли свой канал вблокировка режима ввода / вывода с помощью open, но это не является причиной разницы, которую вы видите.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...