首页 > 解决方案 > 如何保护 Windows 上的 Python 多处理免受不必要的递归

问题描述

所以,我正在做这个项目,其中运行了以下步骤(必然是这样):

在 Linux 上,这可以正常工作。

然而,在 Windows 上,包 P 需要一个守卫来阻止子进程递归地重新导入其父脚本 S(如在Windows 上的 python 多处理中),这会导致无限重复的任务执行。

在脚本 S 中添加一个守卫并不难实现:

if __name__=='__main__':
    #do stuff, call methods from package P

但是,我不希望我的用户在每次调用包时都必须使用该保护,所以我在包 P 中添加了一个保护。它被实现为一个标志,如(为简单起见编辑名称,包有超过 5000 行):

class FirstClass:
    #first method in package P to be executed in script S is FirstClass.__init__
    def __init__(self):
        self.ischild=(multiprocessing.current_process().name != 'MainProcess')
    def some_other_method(self):
        if not self.ischild:
            do_stuff_that_the_package_should_do()

ischild因此,基本上,包 P 的函数和方法只有在脚本 S 实例化的第一个类中的 flag 设置为 False 时才会运行。

它在从命令行调用脚本 S 时起作用,并在重新导入脚本 S 时停止在子进程中执行任何操作 - 因此停止冗余任务和递归子进程创建。

但是,当我尝试将优化包 O 配置为将脚本 S 作为子进程运行时,此守卫停止工作,因为脚本 S 不再是主进程。ischild然后,即使包 O 第一次运行脚本 S,Flag也设置为 True,因为即使调用不是递归的 ,multiprocessing.current_process().name它也不再等于。'MainProcess'

有没有其他方法可以实现对包 P 的保护,以停止其对主进程的递归调用,即使脚本 S 不是主进程也能正常工作?

如果我能准确地确定哪个包/脚本调用了该过程,那就太好了,例如:

if multiprocessing.father()=='package_P':
    ischild=True #stops execution of function do_stuff_the_package_should_do() when the call is recursive

因此,当调用进程既不是主进程(如果脚本 S 是另一个脚本或包的子进程)也不是包 P 的子进程(递归调用)时,就不会造成麻烦。

标签: pythonwindowsmultiprocessing

解决方案


S只需以在导入时不会发生隐式自动多处理的方式重构您的代码。

例如

S/
  __init__.py
  __main__.py

S/__main__.py无论你在做什么,从哪里开始。然后您可以运行python -m S,Python 将调用该主模块。简单地导入S(或来自 的任何东西S)不会这样做。


推荐阅读