Python多处理管道recv()doc不清楚或者我错过了什么?

时间:2011-12-21 18:59:07

标签: python multiprocessing pipe

我最近一直在学习如何使用Python多处理模块,并阅读官方文档。在16.6.1.2. Exchanging objects between processes中有一个关于使用管道交换数据的简单示例。

并且,在16.6.2.4. Connection Objects中,有这样的陈述,引用“如果没有任何东西可以接收而另一端被关闭则引发 EOFError ”。

所以,我修改了如下所示的示例。恕我直言,这应该触发 EOFError 异常:没有发送任何内容,发送端已关闭。

修订后的代码:

from multiprocessing import Process, Pipe

def f(conn):
    #conn.send([42, None, 'hello'])
    conn.close()

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()
    p = Process(target=f, args=(child_conn,))
    p.start()
    #print parent_conn.recv()   # prints "[42, None, 'hello']"
    try:
        print parent_conn.recv()
    except EOFError:
        pass
    p.join()

但是,当我在我的Ubuntu 11.04机器Python 2.7.2上尝试修改过的示例时,脚本挂起了。

如果有人能指出我错过了什么,我会非常感激。

1 个答案:

答案 0 :(得分:9)

当您使用mp.Process启动新进程时,子进程将继承父进程的管道。当子进程关闭conn时,父进程仍然打开child_conn,因此管道文件描述符的引用计数仍然大于0,因此不会引发EOFError。

要获取EOFError,请在父进程和子进程中关闭管道的末尾:

import multiprocessing as mp

def foo_pipe(conn):
    conn.close()

def pipe():
    conn = mp.Pipe()
    parent_conn, child_conn = conn
    proc = mp.Process(target = foo_pipe, args = (child_conn, ))
    proc.start()
    child_conn.close()  # <-- Close the child_conn end in the main process too.
    try:
        print(parent_conn.recv())
    except EOFError as err:
        print('Got here')
    proc.join()

if __name__=='__main__':
    pipe()