gpt4 book ai didi

python - 生成新进程时导入会发生什么情况?

转载 作者:太空宇宙 更新时间:2023-11-03 14:19:49 25 4
gpt4 key购买 nike

生成新进程时导入的模块变量会发生什么情况?

浏览器

with concurrent.futures.ProcessPoolExecutor(max_workers=settings.MAX_PROCESSES) as executor:
for stuff in executor.map(foo, paths):

哪里:

  def foo(str):
x = someOtherModule.fooBar()

foobar 正在访问在 someOtherModule 开头声明的内容:

一些其他模块.py:

 myHat='green'
def fooBar():
return myHat

具体来说,我有一个模块(称为 Y),它在任何函数之外的顶部初始化了一个 py4j 网关。在模块 X 中,我一次加载多个文件,加载后对数据进行排序的函数使用 Y 中的一个函数,该函数又使用网关。

这个设计是pythonic吗?我应该在每个新进程产生后导入我的 Y 模块吗?或者有更好的方法吗?

最佳答案

在 Linux 上,fork 将用于生成子进程,因此父进程的全局范围内的任何内容在子进程中也可用,具有写时复制语义。

在 Windows 上,您在父进程的 __main__ 模块中以模块级别导入 的任何内容都将在子进程中重新导入。

这意味着如果你有一个像这样的父模块(我们称它为 someModule):

import someOtherModule
import concurrent.futures

def foo(str):
x = someOtherModule.fooBar()

if __name__ == "__main__":
with concurrent.futures.ProcessPoolExecutor(max_workers=settings.MAX_PROCESSES) as executor:
for stuff in executor.map(foo, paths):
# stuff

someOtherModule 看起来像这样:

myHat='green'
def fooBar():
return myHat

在这个例子中,someModule 是脚本的 __main__ 模块。因此,在 Linux 上,您在 child 中获得的 myHat 实例将是 someModule 中实例的写时复制版本。在 Windows 上,每个子进程将在加载后立即重新导入 someModule,这将导致 someOtherModule 也被重新导入。

我对 py4j Gateway 对象的了解还不够,无法判断您是否确定这是您想要的行为。如果 Gateway 对象是可腌制的,您可以显式地将它传递给每个 child ,但您必须使用 multiprocessing.Pool 而不是 concurrent.futures .ProcessPoolExecutor:

import someOtherModule
import multiprocessing

def foo(str):
x = someOtherModule.fooBar()

def init(hat):
someOtherModule.myHat = hat

if __name__ == "__main__":
hat = someOtherModule.myHat
pool = multiprocessing.Pool(settings.MAX_PROCESSES,
initializer=init, initargs=(hat,))
for stuff in pool.map(foo, paths):
# stuff

不过,您似乎不需要为您的用例执行此操作。使用重新导入可能没问题。

关于python - 生成新进程时导入会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29203108/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com