Windows上的Python多处理RuntimeError

时间:2015-06-17 01:01:22

标签: python python-2.7 python-multiprocessing

我有一个类函数(让我们称之为“alpha.py”),它使用多处理(processes = 2)来分叉一个进程,并且是我编写的Python包的一部分。在一个单独的Python脚本中(我们称之为“beta.py”),我从这个类中实例化了一个对象并调用了使用多处理的相应函数。最后,所有这些都包含在一个包装Python脚本(让我们称之为“gamma.py”)中,它处理许多不同的类对象和函数。

本质:

  1. 从命令行运行./gamma.py
  2. gamma.py使用子流程并执行beta.py
  3. beta.py从alpha.py类中实例化一个对象并调用使用多处理的函数(processes = 2)
  4. 在Mac或Linux上运行没有问题。但是,它在Windows机器上成为一个问题,错误(和文档)表明我应该在某处写这个:

    if __name__ == '__main__':
        freeze_support()
    

    This other post也提到做同样的事情。

    但是,我不确切地知道这两行应该驻留在哪里。目前,alpha.py,beta.py或gamma.py都不包含if __name__ == '__main__':部分。如果有人能告诉我这两条线应该去哪里以及它背后的基本原理,那将是很棒的。

1 个答案:

答案 0 :(得分:3)

实际上,此处不需要freeze_support()。您获得了RuntimeError,因为您在beta模块的顶层创建并启动了新流程。

在Windows上使用multiprocessing创建新进程时,将在此进程中启动一个新的Python解释器,它将尝试使用应执行的目标函数导入模块。这是您的beta模块。现在,当您导入它时,应执行所有顶级语句,这将导致创建新流程并再次启动。然后,递归地,来自该过程的另一个过程,依此类推。

这很可能不是您想要的,因此当您使用subprocess直接运行beta.py时,应初始化新流程并启动一次。

if __name__ == '__main__':应该放在beta.py中,然后在本节中移动初始化并启动新进程的代码。之后,当导入beta.py而不直接运行时,将不会启动任何新进程,您将看不到任何副作用。