持续读取一个命名管道

4
什么是在Python中连续读取命名管道的最佳方式?
以下是我的当前代码:
def read_commands():
    try:
        print "Creating read pipe..."
        os.mkfifo(pipe_cmd)    # Create pipe
        print "Pipe created!"
    except:
        print "Pipe already exists"

    with open(pipe_cmd, "r") as pipecmd:
        while True:
            try:
                line = pipecmd.readline()
            except:
                print "Could not read cmd pipe"

            if line != "":
                print line

        #time.sleep(1)

然而,当我运行此代码时,它似乎从我的CPU中占用了很多资源(其中一个将达到100%)。使用1秒的延迟可以正常工作。但是,我需要持续读取管道以确保是否有新数据。有更好的方法来完成这个吗?
以下是我在C ++中发送到管道的内容:
void write_pipe(){
    ofstream pipe("/tmp/okccmd");  // Open the pipe
    string data = "Hi";
    pipe << data << endl;
    pipe.flush();
}

谢谢!


查看 select 模块。 - wim
您知道有哪些好的教程可以参考吗? - Luis Cruz
从管道的另一端是否始终有数据可读取?如果没有数据可读取,那么“readline”调用应该会阻塞,所以除非实际上它是不断地读取,否则我很惊讶你看到了CPU峰值。 - dano
这也是我想的...不,数据不应该总是存在。除非我的C++程序将其视为常规文件。我现在该如何知道是否是这种情况?我已经发布了C++代码。 - Luis Cruz
@dano,我刚刚确认了一下... readline 没有阻塞任何东西!while 循环仍在继续。你有什么想法,为什么会出现这种情况? - Luis Cruz
2个回答

3
选择.select在Linux上可以正常运行(不确定Windows是否支持;选择.select似乎可用)。只需查看文档,该模块在标准库中并且有很好的文档(无需知道OS select()函数的实际工作原理)。
文档: https://docs.python.org/3/library/select.html 注意:poll()返回文件描述符列表,而不是文件对象。因此,您应该拥有一个将文件描述符映射到相应对象的字典(即使我只轮询一个文件,我也会这样做)。
pollobj = select.poll()
polled_files = dict()

# the following two lines are reuired for every file
pollobj.register(my_file_obj, <EVENTMASK>)
polled_files[my_file_obj.fileno()] = my_file_obj

for fd, evt in pollobj.poll():
    fileobj = polled_files[fd]
    ... process event for fileobj

这个在交错方式下怎么工作?我想进行轮询,但需要额外的条件。 - kevr
在这个上下文中,“交错”是什么意思?还有什么条件吗?除了您可以在poll()的文档中找到的条件外,没有其他条件。如果您有其他问题,请打开一个新的问题,评论不适合进行后续问题的扩展讨论(请参见[tour] ff)。在提问之前,请进行合理的研究,参见[ask],很可能您的问题已经被问过了,也许是在不同的前提下(使用标准术语还可以增加自己找到答案的机会)。 - too honest for this site

0

你可以使用for..in函数代替readreadline函数。这种方式会以阻塞的方式运行。如果客户端写入FIFO关闭,for循环将结束。而while循环则会重新打开FIFO并等待。

import os

FIFO = 'myfifo'
os.mkfifo(FIFO)
while True:
    with open(FIFO) as fifo:
        for line in fifo:
            print(line)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接