如何保护Windows上的Python多处理免受不必要的递归

问题描述 投票:0回答:1

所以,我正在做这个项目,在其中运行以下步骤(有必要如此):

  • 优化算法程序(程序包O)将飞机分析脚本作为子过程调用;
  • 飞机分析脚本(脚本S)调用了空气动力学软件包;
  • 飞机分析程序包(称为程序包P)创建了多个多处理Process类实例以并行执行繁重的任务。

在Linux上,这没有任何问题。

但是,在Windows上,程序包P需要一个保护措施,以阻止子进程递归地重新导入其父脚本S(如python multiprocessing on Windows中所述,这将导致无限次重复执行任务。

[实现它,在脚本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()

因此,实质上,只有在脚本S实例化的第一类中将标志ischild设置为False时,才运行程序包P的函数和方法。

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

但是,当我尝试配置优化软件包O来将脚本S作为子进程运行时,此防护措施将停止工作,因为脚本S不再是主要进程。然后,即使程序包O首次运行脚本S,标志ischild也将设置为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的子进程(递归调用)时,不会造成麻烦。

python windows multiprocessing
1个回答
0
投票

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

例如

S/
  __init__.py
  __main__.py

只有S/__main__.py开始执行您的操作。然后可以运行python -m S,Python将调用该主模块。简单地导入S(或S中的任何内容)将无法做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.