Typickým způsobem pro UNIX read(2)
vrací 0 bajtů pro označení konce souboru, což může znamenat:
- V souboru již nejsou žádné bajty
- Druhý konec soketu ukončil připojení
- Autor zavřel kanál
Ve vašem případě fifo.read()
vrací prázdný řetězec, protože zapisovač uzavřel svůj deskriptor souboru.
Měli byste tento případ odhalit a opustit smyčku:
reader.py :
import os
import errno
FIFO = 'mypipe'
try:
os.mkfifo(FIFO)
except OSError as oe:
if oe.errno != errno.EEXIST:
raise
print("Opening FIFO...")
with open(FIFO) as fifo:
print("FIFO opened")
while True:
data = fifo.read()
if len(data) == 0:
print("Writer closed")
break
print('Read: "{0}"'.format(data))
Příklad relace
Terminál 1 :
$ python reader.py
Opening FIFO...
<blocks>
Terminál 2 :
$ echo -n 'hello' > mypipe
Terminál 1 :
FIFO opened
Read: "hello"
Writer closed
$
Aktualizace 1 – průběžně znovu otevírat
Uvádíte, že chcete pokračovat v naslouchání zápisům na kanálu, pravděpodobně i poté, co zapisovač zavře.
Chcete-li to provést efektivně, můžete (a měli byste) využít skutečnosti, že
Normálně otevírání bloků FIFO, dokud se neotevře i druhý konec.
Zde přidávám další smyčku kolem open
a read
smyčka. Tímto způsobem, jakmile je roura uzavřena, kód se ji pokusí znovu otevřít, což bude blokováno, dokud ji neotevře jiný zapisovač:
import os
import errno
FIFO = 'mypipe'
try:
os.mkfifo(FIFO)
except OSError as oe:
if oe.errno != errno.EEXIST:
raise
while True:
print("Opening FIFO...")
with open(FIFO) as fifo:
print("FIFO opened")
while True:
data = fifo.read()
if len(data) == 0:
print("Writer closed")
break
print('Read: "{0}"'.format(data))
Terminál 1 :
$ python reader.py
Opening FIFO...
<blocks>
Terminál 2 :
$ echo -n 'hello' > mypipe
Terminál 1 :
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
Terminál 2 :
$ echo -n 'hello' > mypipe
Terminál 1 :
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
... a tak dále.
Více se můžete dozvědět přečtením man
stránka pro potrubí:
- PIPE(7) – Linux Programmer's Manual
- FIFO(7) – Linux Programmer's Manual
(O několik let později) Pokud rozumím případu použití OP pomocí for ... in ...
dělá přesně to, co je požadováno:
import os
FIFO = 'myfifo'
os.mkfifo(FIFO)
with open(FIFO) as fifo:
for line in fifo:
print(line)
Tento program trpělivě čeká na vstup z fifo, dokud není poskytnut, a poté jej vytiskne na obrazovku. Mezitím není použit žádný CPU.
Toto je také více idiomatický způsob v Pythonu, takže bych to doporučil spíše než přímo používat read().
Pokud se na straně klienta zapisující do fifo zavře, smyčka for se ukončí a program se ukončí. Pokud chcete, aby znovu otevřelo fifo a počkalo, až jej otevře další klient, můžete zadat for
sekce do smyčky while:
import os
FIFO = 'myfifo'
os.mkfifo(FIFO)
while True:
with open(FIFO) as fifo:
for line in fifo:
print(line)
Toto znovu otevře fifo a počká jako obvykle.