Python读取名为PIPE [英] Python read named PIPE
问题描述
我在Linux中有一个命名管道,我想从python中读取它.问题是python进程连续消耗"一个内核(100%).我的代码如下:
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()
我想问一下睡眠"是否会帮助这种情况,或者该过程将丢失一些来自管道的输入数据.我无法控制输入,所以我不知道数据输入的频率.我阅读了有关选择和民意调查的信息,但没有找到解决我的问题的任何示例.最后,我想问一下100%的使用率是否会对数据输入产生任何影响(丢失还是什么?).
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:我不想打破循环.我希望该过程连续运行,并听到"管道中的数据.
edit: I don't want to break the loop. I want the process runs continuously and 'hears' for data from the pipe.
推荐答案
在典型的UNIX方式中,read(2)
返回0个字节以指示文件结束,这可能意味着:
In typical UNIX fashion, read(2)
returns 0 bytes to indicate end-of-file which can mean:
- 文件中没有更多字节
- 套接字的另一端已关闭连接
- 作者已关闭管道
在您的情况下,fifo.read()
返回一个空字符串,因为编写器已关闭其文件描述符.
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))
示例会话
第1航站楼:
$ python reader.py
Opening FIFO...
<blocks>
第2航站楼:
$ echo -n 'hello' > mypipe
第1航站楼:
FIFO opened
Read: "hello"
Writer closed
$
更新1-不断重新打开
您表示您想继续监听管道上的写入,大概是在关闭写入器之后也是如此.
Update 1 - Continuously re-open
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
通常,打开FIFO块,直到另一端也打开.
Normally, opening the FIFO blocks until the other end is opened also.
在这里,我在open
和read
循环周围添加了另一个循环.这样,一旦管道关闭,代码将尝试重新打开它,直到其他编写者打开管道为止,该代码将阻塞:
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))
第1航站楼:
$ python reader.py
Opening FIFO...
<blocks>
第2航站楼:
$ echo -n 'hello' > mypipe
第1航站楼:
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
第2航站楼:
$ echo -n 'hello' > mypipe
第1航站楼:
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
...等等.
您可以通过阅读man
管道页面来了解更多信息:
You can learn more by reading the man
page for pipes:
- PIPE(7) - Linux Programmer's Manual
- FIFO(7) - Linux Programmer's Manual
这篇关于Python读取名为PIPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!