理解Python

时间:2015-12-02 15:08:28

标签: python python-2.7 unix pipe named-pipes

我在Unix环境中运行Python 2.7(在Ubuntu和OSX上测试)

我有以下程序:

使用os.open():

[脚本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]

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 = os.open(pipe_2_name, os.O_WRONLY)
    os.write(pipe_2, "client_message_0\n")

    pipe_3 = os.open(pipe_3_name, os.O_WRONLY)
    os.write(pipe_3, "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()

逻辑很简单:

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

完全符合预期。

这是问题所在。我不想使用os.open()。我希望接收一个文件对象并使用它来与管道接口。显然,这并非不可能,因为我可以从带有文件对象的管道中读取。但是,以下脚本不起作用。

没有os.open()

[脚本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。而不是os.open(pipe_name,os.O_WRONLY)我使用pipe = open(pipe_name, 'w')

第二组脚本中发生了什么,不使用os.open(),脚本1在pipe_2 = open(pipe_2_name, 'r')阻塞,而脚本2在pipe_2 = open(pipe_2_name, 'w')阻塞。

  

为什么会这样?

对不起文字墙。我对这个问题感到很困惑。

1 个答案:

答案 0 :(得分:0)

  

第二组脚本中发生了什么,不使用的脚本   os.open(),脚本1在07-10 13:08:12.113 D/dalvikvm( 2154): GREF has increased to 2001 07-10 13:08:12.113 W/dalvikvm( 2154): JNI global reference table (0xb9059ae0) dump: 07-10 13:08:12.113 W/dalvikvm( 2154): Last 10 entries (of 2001): 07-10 13:08:12.113 W/dalvikvm( 2154): 2000: 0xab294a58 android.widget.RelativeLayout$LayoutParams 07-10 13:08:12.113 W/dalvikvm( 2154): 1999: 0xab2949f8 mono.android.view.View_OnClickListenerImplementor 07-10 13:08:12.113 W/dalvikvm( 2154): 1998: 0xab294828 android.widget.RelativeLayout$LayoutParams 07-10 13:08:12.113 W/dalvikvm( 2154): 1997: 0xab294458 android.widget.ImageView 07-10 13:08:12.113 W/dalvikvm( 2154): 1996: 0xab294320 android.widget.RelativeLayout$LayoutParams 07-10 13:08:12.113 W/dalvikvm( 2154): 1995: 0xab2942c0 mono.android.view.View_OnClickListenerImplementor 07-10 13:08:12.113 W/dalvikvm( 2154): 1994: 0xab293cc8 android.widget.TextView 07-10 13:08:12.113 W/dalvikvm( 2154): 1993: 0xab293658 android.widget.RelativeLayout 07-10 13:08:12.113 W/dalvikvm( 2154): 1992: 0xab290998 android.widget.RelativeLayout$LayoutParams 07-10 13:08:12.113 W/dalvikvm( 2154): 1991: 0xab290860 android.widget.RelativeLayout$LayoutParams 07-10 13:08:12.113 W/dalvikvm( 2154): Summary: 处阻塞,而脚本2在pipe_2 = open(pipe_2_name, 'r')处阻塞。

不,脚本2在pipe_2 = open(pipe_2_name, 'w')处阻止。

  

为什么会发生这种情况?

这是因为脚本1的received = pipe_1.readline()[:-1]导致写入的消息以固定大小的块(通常为4096或8192字节)进行缓冲,因此open(pipe_1_name, 'w')尚未向管道写入任何内容,而只是到缓冲区,脚本2没有任何东西可读。请参阅open()以及How often does python flush to a file?

要解决此问题,由于您的消息是完整的行,因此只需使用行缓冲,e。克。

pipe_1.write("server_message_0\n")

(以及其他写管道)。