Python阅读命名PIPE

问题描述:

我有一个在Linux中的命名管道,我想从Python读取它。问题是python进程不断消耗一个核心(100%)。我的代码如下:Python阅读命名PIPE

FIFO = '/var/run/mypipe' 
os.mkfifo(FIFO) 
with open(FIFO) as fifo: 
    while True: 
     line = fifo.read() 

我要问,如果“睡眠”会帮助的情况或处理从管会损失一些输入数据。我无法控制输入,所以我不知道数据输入的频率。我读了关于选择和民意调查,但我没有找到任何我的问题的例子。最后,我想问一下,100%的使用是否会对数据输入产生任何影响(丢失或什么?)。

编辑:我不想打破循环。我希望这个过程持续运行,并'听到'来自管道的数据。

+0

什么'打印(线)'输出的循环?还有你如何写作? –

+0

脚本等待来自另一个进程的数据。如果它带有一个特定字符串的字符串,它会执行一些API调用。 – user1005633

+0

因此,当你打印(行)时,你总是看到循环中的数据? –

在典型的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)) 

例会议

1号航站楼

$ python reader.py 
Opening FIFO... 
<blocks> 

2号航站楼

$ echo -n 'hello' > mypipe 

1号航站楼

FIFO opened 
Read: "hello" 
Writer closed 
$ 

更新1 - 不断地重新打开

表明您想保留名单即使在作家关闭之后,也可能会写入管道。

为了有效地做到这一点,你可以(也应该)采取的是

通常情况下,打开FIFO模块,直至另一端也打开了事实。

在这里,我在openread循环周围添加了另一个循环。这样一来,一旦管道被关闭,该代码将尝试重新打开它,这将阻止,直到另一位作家打开管道:

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页管道了解更多:

+0

我不想打破循环。我想连续阅读。该脚本等待来自另一个进程的数据。如果它带有一个特定字符串的字符串,它会执行一些API调用... – user1005633

+0

*“我想连续阅读它。”*不,你不知道。这就是导致100%CPU利用率的原因。正如你可以在我的更新示例中看到的,“打开”阻止,直到有一个作者。你想要做的就是关闭管道,然后在你重新打开它时允许“打开”阻塞。查看我的更新1. –

+0

我强烈建议您充分阅读我已链接的手册页,并且完全理解管道/ fifo的开放,读取和写入语义。 –