gpt4 book ai didi

python - 多处理是否在这种情况下复制对象?

转载 作者:太空宇宙 更新时间:2023-11-04 01:47:03 24 4
gpt4 key购买 nike

import multiprocessing
import numpy as np
import multiprocessing as mp
import ctypes

class Test():
def __init__(self):
shared_array_base = multiprocessing.Array(ctypes.c_double, 100, lock=False)
self.a = shared_array = np.ctypeslib.as_array(shared_array_base)

def my_fun(self,i):
self.a[i] = 1

if __name__ == "__main__":
num_cores = multiprocessing.cpu_count()

t = Test()

def my_fun_wrapper(i):
t.my_fun(i)

with mp.Pool(num_cores) as p:
p.map(my_fun_wrapper, np.arange(100))

print(t.a)

在上面的代码中,我尝试使用 multiprocessing 编写代码来修改数组。在每个进程中执行的函数 my_fun() 应该修改数组 a[:] 的值在作为参数传递给 my_fun() 的索引 i 处。关于上面的代码,我想知道正在复制什么。

1) 每个进程是否复制了代码中的任何内容?我认为该对象可能是,但理想情况下什么都不是。

2) 有没有办法绕过对对象使用包装函数 my_fun()

最佳答案

您的代码中的几乎所有内容都会被复制,除了您使用 multiprocessing.Array 分配的共享内存。 multiprocessing 充满了不直观的隐式副本。


当您在 multiprocessing 中生成一个新进程时,新进程需要它自己的原始进程中几乎所有内容的版本。这取决于平台和设置的不同处理方式,但我们可以告诉您正在使用“fork”模式,因为您的代码不会在“spawn”或“forkserver”模式下工作 - 您会收到有关 workers not 的错误能够找到 my_fun_wrapper。 (Windows 仅支持“spawn”,因此我们可以判断您不在 Windows 上。)

在“fork”模式下,这个初始副本是通过使用 fork 系统调用要求操作系统复制整个进程和里面的所有内容来完成的。 multiprocessing.Array 分配的内存有点“外部”,不会被复制,但大多数其他东西都是。 (也有写时复制优化,但写时复制仍然表现得好像一切都被复制了,并且由于引用计数更新,优化在 Python 中效果不佳。)

当您将任务分派(dispatch)给工作进程时,multiprocessing 需要制作更多副本。任何参数,以及任务本身的可调用对象,都是主进程中的对象,对象本质上只存在于一个进程中。 worker 无法访问任何这些。他们需要自己的版本。 multiprocessing 通过 pickle 可调用对象和参数、通过进程间通信发送序列化字节以及在 worker 中取消 pickle 来处理第二轮副本。


当 master pickle my_fun_wrapper 时,pickle 只是说“在 __main__ 模块中寻找 my_fun_wrapper 函数”,而 worker 们则看升级他们的 my_fun_wrapper 版本来解开它。 my_fun_wrapper 寻找一个全局的 t,在 workers 中,那个 t 是由 fork 产生的,而 fork 产生了一个 t 包含一个由您在原始 multiprocessing.Array 调用中分配的共享内存支持的数组。

另一方面,如果您尝试将 t.my_fun 传递给 p.map,则 multiprocessing 必须 pickle 和 unpickle a方法对象。生成的 pickle 不会说“查找 t 全局变量并获取其 my_fun 方法”。泡菜说要构建一个 Test 实例并获取its my_fun 方法。 pickle 中没有任何关于使用您分配的共享内存的说明,生成的 Test 实例及其数组独立于您要修改的原始数组。


我知道没有什么好方法可以避免需要某种包装函数。

关于python - 多处理是否在这种情况下复制对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58869012/

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