简体   繁体   English

Windows上的Python多处理RuntimeError

[英]Python Multiprocessing RuntimeError on Windows

I have a class function (let's call it "alpha.py") that uses multiprocessing (processes=2) to fork a process and is part of a Python package that I wrote. 我有一个类函数(让我们称之为“alpha.py”),它使用多处理(processes = 2)来分叉一个进程,并且是我编写的Python包的一部分。 In a separate Python script (let's call it "beta.py"), I instantiated an object from this class and called the corresponding function that uses multiprocessing. 在一个单独的Python脚本中(我们称之为“beta.py”),我从这个类中实例化了一个对象并调用了使用多处理的相应函数。 Finally, all of this is wrapped inside a wrapper Python script (let's call this "gamma.py") that handles many different class objects and functions. 最后,所有这些都包含在一个包装Python脚本(让我们称之为“gamma.py”)中,它处理许多不同的类对象和函数。

Essentially: 实质上:

  1. Run ./gamma.py from the command line 从命令行运行./gamma.py
  2. gamma.py uses subprocess and executes beta.py gamma.py使用子进程并执行beta.py.
  3. beta.py instantiates an object from the alpha.py class and calls the function which uses multiprocessing (processes=2) beta.py从alpha.py类中实例化一个对象并调用使用多处理的函数(processes = 2)

This has no problems being run on a Mac or Linux. 这在Mac或Linux上运行没有问题。 However, it becomes a problem on a Windows machine and the error (and documentation) suggests that I should write this somewhere: 但是,它在Windows机器上成为一个问题,错误(和文档)表明我应该在某处写这个:

if __name__ == '__main__':
    freeze_support()

This other post also mentions doing the same thing. 这篇文章还提到做同样的事情。

However, I don't know exactly where these two lines should reside. 但是,我不确切知道这两行应该驻留在哪里。 Currently, neither alpha.py, beta.py, or gamma.py contains an if __name__ == '__main__': section. 目前,alpha.py,beta.py或gamma.py都不包含if __name__ == '__main__':部分。 It would be great if somebody can tell me where these two lines should go and also the rationale behind it. 如果有人能告诉我这两条线应该去哪里以及它背后的基本原理,那将是很棒的。

Actually, freeze_support() is not needed here. 实际上,这里不需要freeze_support() You get a RuntimeError because you create and start your new processes at the top level of your beta module. 您会收到RuntimeError因为您在beta模块的顶层创建并启动了新流程。

When a new process is created using multiprocessing on Windows, a new Python interpreter will be started in this process and it will try to import the module with the target function that should be executed. 当在Windows上使用multiprocessing处理创建新进程时,将在此进程中启动一个新的Python解释器,它将尝试使用应执行的目标函数导入该模块。 This is your beta module. 这是您的beta模块。 Now, when you import it, all your top level statements should be executed which will cause a new process to be created and started again. 现在,当您导入它时,应执行所有顶级语句,这将导致创建新流程并再次启动。 And then, recursively, another process from that process, and so on and so forth. 然后,递归地,来自该过程的另一个过程,依此类推。

This is most likely not what you want, thus new processes should be initialized and started only once, when you run beta.py directly with a subprocess . 这很可能不是您想要的,因此当您使用subprocess进程直接运行beta.py时,应该初始化新进程并仅启动一次。

if __name__ == '__main__': should be placed in beta.py, then move initialization and start code for your new processes in this section. if __name__ == '__main__':应该放在beta.py中,然后在本节中移动初始化并启动新进程的代码。 After that, when beta.py will be imported and not run directly, no new process will be started and you will not see any side effects. 之后,当导入beta.py而不直接运行时,将不会启动任何新进程,您将看不到任何副作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM