python3:select()在UNIX FIFO中表现得很奇怪

时间:2018-10-27 07:40:13

标签: python linux python-3.x unix select

我正在尝试在UNIX FIFO上等待某些输入字符串。我正在使用select()等待FD准备读取。这是我的代码第一次按预期方式等待,但是即使FD不再准备读取,select()仍会成功返回。

这是我的代码:

#! /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

更新:

使用仍然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 :(得分:1)

我能够通过将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:~#