use*_*633 8 python linux named-pipes
我在linux中有一个命名管道,我想从python中读取它.问题是python进程'消耗'一个核心(100%)连续.我的代码如下:
FIFO = '/var/run/mypipe'
os.mkfifo(FIFO)
with open(FIFO) as fifo:
while True:
line = fifo.read()
Run Code Online (Sandbox Code Playgroud)
我想问一下'sleep'是否有助于这种情况或进程是否会从管道中丢失一些输入数据.我无法控制输入,所以我不知道数据输入的频率.我读了关于选择和民意调查,但我找不到任何关于我的问题的例子.最后,我想询问100%的使用量是否会对数据输入产生任何影响(丢失或什么?).
编辑:我不想打破循环.我希望流程能够持续运行,并且可以"听到"来自管道的数据.
Jon*_*art 22
在典型的UNIX方式中,read(2)返回0个字节以指示文件结尾,这可能意味着:
在您的情况下,fifo.read()返回一个空字符串,因为编写器已关闭其文件描述符.
你应该检测到这种情况并突破你的循环:
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))
Run Code Online (Sandbox Code Playgroud)
示例会话
1号航站楼:
$ python reader.py
Opening FIFO...
<blocks>
Run Code Online (Sandbox Code Playgroud)
2号航站楼:
$ echo -n 'hello' > mypipe
Run Code Online (Sandbox Code Playgroud)
1号航站楼:
FIFO opened
Read: "hello"
Writer closed
$
Run Code Online (Sandbox Code Playgroud)
你表明你想继续监听管道上的写入,大概是在作家关闭之后.
为了有效地做到这一点,你可以(并且应该)利用这一事实
通常,打开FIFO块直到另一端打开.
在这里,我添加了另一个循环open和read循环.这样,一旦管道关闭,代码将尝试重新打开它,这将阻塞,直到另一个编写器打开管道:
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))
Run Code Online (Sandbox Code Playgroud)
1号航站楼:
$ python reader.py
Opening FIFO...
<blocks>
Run Code Online (Sandbox Code Playgroud)
2号航站楼:
$ echo -n 'hello' > mypipe
Run Code Online (Sandbox Code Playgroud)
1号航站楼:
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
Run Code Online (Sandbox Code Playgroud)
2号航站楼:
$ echo -n 'hello' > mypipe
Run Code Online (Sandbox Code Playgroud)
1号航站楼:
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
Run Code Online (Sandbox Code Playgroud)
... 等等.
您可以通过阅读man管道页面了解更多信息:
(多年后)如果我理解 OP 的用例 usingfor ... in ...正是想要的:
import os
FIFO = 'myfifo'
os.mkfifo(FIFO)
with open(FIFO) as fifo:
for line in fifo:
print(line)
Run Code Online (Sandbox Code Playgroud)
该程序耐心地等待来自 fifo 的输入,直到提供,然后将其打印在屏幕上。在此期间不使用 CPU。
这也是 Python 中更惯用的方式,所以我推荐它而不是直接使用 read() 。
如果客户端写入 fifo 关闭,则 for 循环结束并且程序退出。如果您希望它重新打开 fifo 以等待下一个客户端打开它,您可以将该for部分放入一个 while 循环中:
import os
FIFO = 'myfifo'
os.mkfifo(FIFO)
while True:
with open(FIFO) as fifo:
for line in fifo:
print(line)
Run Code Online (Sandbox Code Playgroud)
这将重新打开fifo并像往常一样等待。