Python读取命名的PIPE

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

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

我想问一下,“睡眠”是否有助于这种情况,或者这个过程是否会丢失pipe道中的一些input数据。 我无法控制input,所以我不知道数据input的频率。 我读了select和民意调查,但我没有find我的问题的任何例子。 最后,我想问一下,100%的使用是否会对数据input产生影响(丢失或者是什么?)。

编辑:我不想打破循环。 我希望这个过程持续运行,并从pipe道中“听到”数据。

在典型的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页来了解更多信息:

  • PIPE(7) – Linux程序员手册
  • FIFO(7) – Linux程序员手册