【问题标题】:Python multiprocessing pipe recv() doc unclear or did I miss anything?Python 多处理管道 recv() 文档不清楚还是我错过了什么?
【发布时间】:2011-12-21 18:59:07
【问题描述】:

我最近一直在学习如何使用 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 上尝试修改后的示例时,脚本挂起。

如果有人能指出我错过了什么,我将不胜感激。

【问题讨论】:

  • 请删除“或有错误”。出现错误的概率几乎为零。专注于可能的解释——误读或不清楚的文档。
  • @S.Lott,你是对的。这是我的疏忽——根本不是错误。忘记了 Python 的引用计数,以及使用双工管道的最佳实践。

标签: python multiprocessing pipe


【解决方案1】:

当您使用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()

【讨论】:

  • 也在 python 3.8 中验证。孩子和他的父母之间只有一个管道(双向),有两端。关闭 child_conn 不会删除管道。 EOFError 仅在管道为空时引发(如果孩子没有发送任何内容),并且 child_conn 从两侧关闭。如果没有从 parent 侧关闭且 pipe 为空,则 parent_conn.recv() 等待... 即使 child_conn 两侧关闭,此变量仍然存在于 pipe() 中(它的引用计数不为 0),但 parent 什么都没有期望孩子,所以EOFError。
  • 如果 foo_pipe() 没有关闭连接,结果是一样的。总而言之,EOFError是当child什么都不发送,而parent在接收之前关闭了child连接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-31
  • 2014-03-14
  • 2017-08-23
相关资源
最近更新 更多