python3: select () ведет себя странно с UNIX FIFO - PullRequest
0 голосов
/ 27 октября 2018

Я пытаюсь подождать в UNIX FIFO для какой-либо входной строки. Я использую select () для ожидания на FD, чтобы быть готовым к чтению. В первый раз мой код ожидает, как ожидалось, но затем select () продолжает возвращаться с успехом, даже если FD больше не готов к чтению.

Вот мой код:

#! /usr/bin/python3

import errno
import time
import sys
import os
import select
import string

myInput = './inFIFO'
try:
    if os.path.exists(myInput):
        os.unlink(myInput)
    os.mkfifo(myInput)
except Exception as e:
    sys.stderr.write("ERROR: " + str(e))
    sys.exit(2)

sIn = open(myInput, 'r')

try:
    loop = 5
    while loop:
        loop = loop - 1
        readMe = select.select([sIn], [], [])[0]
        print(readMe, file = sys.stderr);
        if len(readMe):
            a = sIn.readlines()
            print('Message <|' + ''.join(a) + '|>', file = sys.stderr)
            sIn.flush()
except Exception as e:
    sys.stderr.write('ERROR: ' + str(e))
    sys.stdin.close()
    sys.stdout.close()
    sys.stderr.close()
    os.unlink(myStdin)
    sys.exit(1)

Вот вывод:

root:~# ./select.py &
[1] 4035
root:~# echo 'Hello World !!!' > ./inFIFO
root:~# [<_io.TextIOWrapper name='./inFIFO' mode='r' encoding='UTF-8'>]
Message <|Hello World !!!
|>
[<_io.TextIOWrapper name='./inFIFO' mode='r' encoding='UTF-8'>]
Message <||>
[<_io.TextIOWrapper name='./inFIFO' mode='r' encoding='UTF-8'>]
Message <||>
[<_io.TextIOWrapper name='./inFIFO' mode='r' encoding='UTF-8'>]
Message <||>
[<_io.TextIOWrapper name='./inFIFO' mode='r' encoding='UTF-8'>]
Message <||>

[1]+  Done                    ./select.py
root:~#

Почему select () ведет себя необычно? Я использую LinuxMint 19 amd64 и Python 3.6.6

UPDATE:

Обновлен код с os.read() все та же история ...

Новый код:

#! /usr/bin/python3

import errno
import time
import sys
import os
import select
import string

myInput = './inFIFO'
try:
    if os.path.exists(myInput):
        os.unlink(myInput)
    os.mkfifo(myInput)
except Exception as e:
    sys.stderr.write("ERROR: " + str(e))
    sys.exit(2)

sIn = open(myInput, 'r')

try:
    loop = 5
    while loop:
        loop = loop - 1
        readMe = select.select([sIn], [], [])[0]
        print(readMe, file = sys.stderr);
        if len(readMe):
            a = os.read(sIn.fileno(), 8192).decode()
            print('Message <|' + ''.join(a) + '|>', file = sys.stderr)
            sIn.flush()
except Exception as e:
    sys.stderr.write('ERROR: ' + str(e))
    sys.stdin.close()
    sys.stdout.close()
    sys.stderr.close()
    os.unlink(myStdin)
    sys.exit(1)

Теперь вывод:

root:~# ./select.py &
[1] 4099
root:~# echo 'Hello World !!!' > ./inFIFO
root:~# [<_io.TextIOWrapper name='./inFIFO' mode='r' encoding='UTF-8'>]
Message <|Hello World !!!
|>
[<_io.TextIOWrapper name='./inFIFO' mode='r' encoding='UTF-8'>]
Message <||>
[<_io.TextIOWrapper name='./inFIFO' mode='r' encoding='UTF-8'>]
Message <||>
[<_io.TextIOWrapper name='./inFIFO' mode='r' encoding='UTF-8'>]
Message <||>
[<_io.TextIOWrapper name='./inFIFO' mode='r' encoding='UTF-8'>]
Message <||>

[1]+  Done                    ./select.py
root:~#

1 Ответ

0 голосов
/ 27 октября 2018

Мне удалось решить проблему, открыв FIFO в режиме READ-WRITE и NON-BLOCK I / O.

Мой рабочий код:

#! /usr/bin/python3

import errno
import time
import sys
import os
import select
import string

myInput = './inFIFO'
try:
    if os.path.exists(myInput):
        os.unlink(myInput)
    os.mkfifo(myInput)
except Exception as e:
    sys.stderr.write("ERROR: " + str(e))
    sys.exit(2)

inFD = os.open(myInput, os.O_RDWR | os.O_NONBLOCK)
sIn = os.fdopen(inFD, 'r')

try:
    loop = 5
    while loop:
        loop = loop - 1
        readMe = select.select([sIn], [], [])[0]
        print(readMe, file = sys.stderr);
        if len(readMe):
            a = sIn.read()
            print('Message <|' + ''.join(a) + '|>', file = sys.stderr)
except Exception as e:
    sys.stderr.write('ERROR: ' + str(e))
    sys.stdin.close()
    sys.stdout.close()
    sys.stderr.close()
    os.unlink(myStdin)
    sys.exit(1)

Выход:

root:~# ./select.py &
[1] 4179
root:~# echo 'Hello World !!!' > ./inFIFO
root:~# [<_io.TextIOWrapper name=3 mode='r' encoding='UTF-8'>]
Message <|Hello World !!!
|>

root:~# echo 'Hello World !!!' > ./inFIFO
[<_io.TextIOWrapper name=3 mode='r' encoding='UTF-8'>]
Message <|Hello World !!!
|>
root:~#
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...