Python 读取命名 PIPE
Python read named PIPE
我在 linux 中有一个命名管道,我想从 python 中读取它。问题是 python 进程 'consumes' 一个核心 (100%) 连续。我的代码如下:
FIFO = '/var/run/mypipe'
os.mkfifo(FIFO)
with open(FIFO) as fifo:
while True:
line = fifo.read()
我想问一下 'sleep' 是否会对这种情况或进程从管道丢失一些输入数据有所帮助。我无法控制输入,所以我不知道数据输入的频率。我阅读了 select 和民意调查,但我没有找到我的问题的任何例子。最后想问下100%使用率对数据输入有没有影响(丢失什么的?)。
编辑:我不想打破循环。我希望进程连续运行并且 'hears' 来自管道的数据。
以典型的 UNIX 方式,read(2)
returns 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))
示例会话
1 号航站楼:
$ python reader.py
Opening FIFO...
<blocks>
2号航站楼:
$ echo -n 'hello' > mypipe
1 号航站楼:
FIFO opened
Read: "hello"
Writer closed
$
更新 1 - 持续重新打开
你表示你想继续监听管道上的写入,大概即使在写入器关闭之后也是如此。
要有效地做到这一点,您可以(并且应该)利用
Normally, opening the FIFO blocks until the other end is opened also.
在这里,我在 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))
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
页面了解更多信息:
(多年后)如果我使用 for ... in ...
理解 OP 的用例,则完全符合要求:
import os
FIFO = 'myfifo'
os.mkfifo(FIFO)
with open(FIFO) as fifo:
for line in fifo:
print(line)
此程序耐心等待来自 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)
这将重新打开 fifo 并照常等待。
我在 linux 中有一个命名管道,我想从 python 中读取它。问题是 python 进程 'consumes' 一个核心 (100%) 连续。我的代码如下:
FIFO = '/var/run/mypipe'
os.mkfifo(FIFO)
with open(FIFO) as fifo:
while True:
line = fifo.read()
我想问一下 'sleep' 是否会对这种情况或进程从管道丢失一些输入数据有所帮助。我无法控制输入,所以我不知道数据输入的频率。我阅读了 select 和民意调查,但我没有找到我的问题的任何例子。最后想问下100%使用率对数据输入有没有影响(丢失什么的?)。
编辑:我不想打破循环。我希望进程连续运行并且 'hears' 来自管道的数据。
以典型的 UNIX 方式,read(2)
returns 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))
示例会话
1 号航站楼:
$ python reader.py
Opening FIFO...
<blocks>
2号航站楼:
$ echo -n 'hello' > mypipe
1 号航站楼:
FIFO opened
Read: "hello"
Writer closed
$
更新 1 - 持续重新打开
你表示你想继续监听管道上的写入,大概即使在写入器关闭之后也是如此。
要有效地做到这一点,您可以(并且应该)利用
Normally, opening the FIFO blocks until the other end is opened also.
在这里,我在 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))
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
页面了解更多信息:
(多年后)如果我使用 for ... in ...
理解 OP 的用例,则完全符合要求:
import os
FIFO = 'myfifo'
os.mkfifo(FIFO)
with open(FIFO) as fifo:
for line in fifo:
print(line)
此程序耐心等待来自 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)
这将重新打开 fifo 并照常等待。