Python读取名为PIPE [英] Python read named PIPE

查看:121
本文介绍了Python读取名为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.

在这里,我在openread循环周围添加了另一个循环.这样,一旦管道关闭,代码将尝试重新打开它,直到其他编写者打开管道为止,该代码将阻塞:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆