理解Python中的命名管道(FIFO)

2024-04-20 12:06:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Unix环境下运行python2.7(在Ubuntu和OSX上测试)

我有以下项目:


与操作系统打开():

[脚本1]

import os

pipe_1_name = "pipe_1"
pipe_2_name = "pipe_2"
pipe_3_name = "pipe_3"


def set_connection():
    pipe_names = [pipe_1_name, pipe_2_name, pipe_3_name]
    for pipe_name in pipe_names:
        if os.path.exists(pipe_name):
            os.remove(pipe_name)
            os.mkfifo(pipe_name)
        else:
            os.mkfifo(pipe_name)

    pipe_1 = os.open(pipe_1_name, os.O_WRONLY)
    os.write(pipe_1, "server_message_0\n")

    pipe_2 = open(pipe_2_name, 'r')
    received = pipe_2.readline()[:-1]
    print "[0] Now processing if received is correct: " + received

    pipe_3 = open(pipe_3_name, 'r')
    received = pipe_3.readline()[:-1]
    print "[1] Now processing if received is correct: " + received

    print "Connection established."
    return pipe_1,pipe_2,pipe_3


def main():
    pipe_1, pipe_2, pipe_3 = set_connection()

    print str(pipe_1)
    print str(pipe_2)
    print str(pipe_3)

if __name__ == "__main__":
    main()

[脚本2]

^{pr2}$

逻辑很简单:

[管道1] 1脚本1打开到脚本2的写入管道。 2脚本2从管道中读取。 [管道2] 三。脚本2打开脚本1的写入管道。 4脚本1从管道中读取。 [管道3] 5脚本2打开脚本1的写入管道。 6脚本1从管道中读取。在

完全符合预期。在


问题就在这里。我不想用操作系统打开(). 我希望接收一个文件对象,并使用它与管道接口。显然,这并不是不可能的,因为我可以从带有file对象的管道中读取数据。但是,以下脚本不起作用。在


没有操作系统打开()

[脚本1]

import os

pipe_1_name = "pipe_1"
pipe_2_name = "pipe_2"
pipe_3_name = "pipe_3"


def set_connection():
    pipe_names = [pipe_1_name, pipe_2_name, pipe_3_name]
    for pipe_name in pipe_names:
        if os.path.exists(pipe_name):
            os.remove(pipe_name)
            os.mkfifo(pipe_name)
        else:
            os.mkfifo(pipe_name)

    pipe_1 = open(pipe_1_name, 'w')
    pipe_1.write("server_message_0\n")

    pipe_2 = open(pipe_2_name, 'r')
    received = pipe_2.readline()[:-1]
    print "[0] Now processing if received is correct: " + received

    pipe_3 = open(pipe_3_name, 'r')
    received = pipe_3.readline()[:-1]
    print "[1] Now processing if received is correct: " + received

    print "Connection established."
    return pipe_1,pipe_2,pipe_3


def main():
    pipe_1, pipe_2, pipe_3 = set_connection()

    print str(pipe_1)
    print str(pipe_2)
    print str(pipe_3)

if __name__ == "__main__":
    main()

[脚本2]

import os

pipe_1_name = "pipe_1"
pipe_2_name = "pipe_2"
pipe_3_name = "pipe_3"


def get_connection():
    pipe_names = [pipe_1_name, pipe_2_name, pipe_3_name]
    for pipe_name in pipe_names:
        if not os.path.exists(pipe_name):
            raise Exception("Pipe "+pipe_name+" does not exist!")

    pipe_1 = open(pipe_1_name, 'r')
    received = pipe_1.readline()[:-1]
    print "[0] Now processing if received is correct: " + received

    pipe_2 = open(pipe_2_name, 'w')
    pipe_2.write("client_message_0\n")

    pipe_3 = open(pipe_3_name, 'w')
    pipe_3.write("client_message_1\n")

    print "Connection established."
    return pipe_1,pipe_2,pipe_3


def main():
    pipe_1, pipe_2, pipe_3 = get_connection()

    print str(pipe_1)
    print str(pipe_2)
    print str(pipe_3)

if __name__ == "__main__":
    main()

他们看起来一样,不是吗?唯一的区别是我如何打开fifo。我用pipe = open(pipe_name, 'w')代替os.open(pipe_name,os.O_WRONLY)。在


在第二组脚本中,没有使用的脚本会发生什么操作系统打开(),脚本1在pipe_2 = open(pipe_2_name, 'r')处阻塞,而脚本2在pipe_2 = open(pipe_2_name, 'w')处阻塞。在

Why is this happening?

对不起,这是一堵墙。我真的很困惑这个问题。在


Tags: name脚本if管道namesisosmain
1条回答
网友
1楼 · 发布于 2024-04-20 12:06:26

What happens in the second set of scripts, the ones that don't use os.open(), Script 1 blocks at pipe_2 = open(pipe_2_name, 'r') while Script 2 blocks at pipe_2 = open(pipe_2_name, 'w').

不,在received = pipe_1.readline()[:-1]处编写2个块的脚本。在

Why is this happening?

这是因为脚本1的open(pipe_1_name, 'w')会导致写入的消息以固定大小的块(通常为4096或8192字节)进行缓冲,因此pipe_1.write("server_message_0\n")还没有向管道写入任何内容,而只向缓冲区写入任何内容,而脚本2不获取任何要读取的内容。请参见open()和{a2}

为了解决这个问题,因为您的消息是完整的行,所以使用行缓冲就足够了

    pipe_1 = open(pipe_1_name, 'w', 1)

(以及其他写入管道)。在

相关问题 更多 >