为什么对 python 模块的变量所做的修改不会传播到新的并行进程?

Why aren't modifications made to a python module's variables propagating to new parallel processes?

提问人:OneTimeShot 提问时间:11/16/2023 更新时间:11/17/2023 访问量:33

问:

我有一个令人尴尬的平行任务列表,列出了我想要执行的任务。目前,我正在将这些任务的配置作为模块导入。

单行 configuration.py 示例:

result_folder = "aFolder"

到目前为止,我一直在串联而不是并行调用我的函数

def embarassing(x, conf):
    print(x)
    print(conf.result_folder)
    # ... do complicated things and return a value

if __name__ == "main":
    import configuration as conf
    x = 1
    y = embarassing(x, conf)

现在,我更新了代码,以利用并行运行这些任务。

from dask.distributed import Client
# ...
if __name__ == "main":
    import configuration as conf
    client = Client(n_workers=1)
    x = 1
    future = client.submit(embarassing, x, conf)
    y = future.result()

这一切都很好。问题是有时我想运行一组临时案例,直到现在我总是可以添加

import configuration as conf
x = 2
conf.result_folder = "newFold"

代码将打印出来

2
newFold

但在并行代码下,它会打印

2
aFolder

为什么我不能再将此模块作为参数传递?

python-multiprocessing python-module dask-distributed

评论

0赞 Frank Yellin 11/16/2023
您已创建单独的流程。在一个进程中所做的更改不会被任何其他进程看到。通常,在设置 之前,不应启动第二个进程。进程之间有多种通信方式,但它们需要一点努力。conf.result_folder
0赞 OneTimeShot 11/16/2023
我在创建更多进程之前进行设置。 并紧跟在导入的行之后。这就是实现变革的原因。conf.result_folderxconf.result_folderconfx
0赞 MegaIng 11/17/2023
你在哪里添加代码?部分内的内容不会在额外的进程中执行。__name__=="__main__"

答:

0赞 mdurant 11/17/2023 #1

Distributed 使用 pickle 将值发送给 worker。对于模块,这本质上只是模块的名称,因此工作线程执行导入,而不是保存模块的当前状态,发送该状态,然后在工作线程中重新创建它。

如果要以这种方式向工作线程任务发送信息,则需要发送普通变量(类实例等)而不是模块对象。或者,您可以进行闭合,或在工作器上运行生产线,或者......可能有很多选择。conf.result_folder = "newFold"