I have a named pipe in linux and i want to read it from python. The problem is that the python process 'consumes' one core (100%) continuously. My code is the following:
FIFO = '/var/run/mypipe'
os.mkfifo(FIFO)
with open(FIFO) as fifo:
while True:
line = fifo.read()
I want to ask if the 'sleep' will help the situation or the process going to loss some input data from pipe. I can't control the input so i don't know the frequency of data input. I read about select and poll but i didn't find any example for my problem. Finally, i want to ask if the 100% usage will have any impact on the data input(loss or something?).
edit: I don't want to break the loop. I want the process runs continuously and 'hears' for data from the pipe.
In typical UNIX fashion, read(2)
returns 0 bytes to indicate end-of-file which can mean:
In your case, fifo.read()
is returning an empty string, because the writer has closed its file descriptor.
You should detect that case and break out of your loop:
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))
Example session
Terminal 1:
$ python reader.py
Opening FIFO...
<blocks>
Terminal 2:
$ echo -n 'hello' > mypipe
Terminal 1:
FIFO opened
Read: "hello"
Writer closed
$
You indicate that you want to keep listening for writes on the pipe, presumably even after a writer has closed.
To do this efficiently, you can (and should) take advantage of the fact that
Normally, opening the FIFO blocks until the other end is opened also.
Here, I add another loop around open
and the read
loop. This way, once the pipe is closed, the code will attempt to re-open it, which will block until another writer opens the pipe:
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))
Terminal 1:
$ python reader.py
Opening FIFO...
<blocks>
Terminal 2:
$ echo -n 'hello' > mypipe
Terminal 1:
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
Terminal 2:
$ echo -n 'hello' > mypipe
Terminal 1:
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
... and so on.
You can learn more by reading the man
page for pipes: