Python 并行执行实例方法[以前:多处理-实例变量得到覆盖]
蟒蛇学家 这是我的类定义Python 并行执行实例方法[以前:多处理-实例变量得到覆盖],python,python-3.x,multiprocessing,Python,Python 3.x,Multiprocessing,蟒蛇学家 这是我的类定义 class Test(): def __init__(self, num): self.num = num self.out_come = multiprocessing.Manager.list() def func1(self): for n in range(self.num): self.out_come.append(numpy.random.randn(1)[0])
class Test():
def __init__(self, num):
self.num = num
self.out_come = multiprocessing.Manager.list()
def func1(self):
for n in range(self.num):
self.out_come.append(numpy.random.randn(1)[0])
return self.out_come
我正在举例说明:
obj_l = []
for lettr in list(string.ascii_uppercase)[:5]:
lettr = Test(0.2) # Initiating the class
obj_l.append(lettr)
我想并行运行实例方法,如下所示:
proc = []
for n in range(len(obj_l)):
proc.append(multiprocessing.Process(target=obj_l[n].func1, args=(param[n],))
for p in proc: p.start()
for p in proc: p.join()
但是,当我尝试访问函数的结果时,self.out\u come
。对于所有对象,我都得到相同的结果。看起来,self.out\u come
被覆盖了。如果我错了,请纠正我,并建议我如何并行运行实例方法
编辑-1:
问题似乎出在多处理.Manager.list()
上。正在寻找获得这项工作的方法。非常感谢您的帮助
编辑-2:
multiprocessing.Manager.list()
只是访问Test
类的self.out\u come
实例的代理。看起来,这样我只能访问代理,而不能访问每个self.out\u come
实例
我尝试了另一种使用线程的方法。我无法实现我想要的:每个人都是自己。出来的人都是分开处理的。然而,我没有得到任何加速(由于吉尔)。本质上,是串行运行,没有任何并行化
我尝试过使用多处理.Queue
,但没有成功
还有其他建议/想法吗?(numba或cython)为了完成,将此作为答案发布:
对于那些想要并行执行实例方法的人来说,Python似乎给了他们一段艰难的时间,如果不是不可能的话
我已经找到了一种方法,通过使用。虽然这要求您的所有类都是Chare
父类的子类,但我认为这是可以实现的
它是写在魅力+++ >代码> C++上的分布式计算平台。p>
对于那些觉得这很有帮助的人,干杯
我认为您看到的问题是,您的所有进程都共享同一个随机种子,如果我修复代码中的错误,并向分布式函数添加一个随机种子,那么一切似乎都正常。试着用下面的随机种子来注释这一行,然后再次运行它
import multiprocessing
import string
import numpy
class Test():
def __init__(self, num):
self.num = num
self.out_come = multiprocessing.Manager().list()
def func1(self):
numpy.random.seed(self.num)
for n in range(self.num):
self.out_come.append(numpy.random.randn(1)[0])
return self.out_come
obj_l = []
for s in range(1, 6):
lettr = Test(s) # Initiating the class
obj_l.append(lettr)
proc = []
for n in range(len(obj_l)):
proc.append(multiprocessing.Process(target=obj_l[n].func1))
for p in proc:
p.start()
for p in proc:
p.join()
for i in obj_l:
print(i.out_come)
# [1.6243453636632417]
# [-0.4167578474054706, -0.056266827226329474]
# [1.7886284734303186, 0.43650985051198943, 0.09649746807200862]
# [0.05056170714293955, 0.499951333237829, -0.9959089311068651, 0.6935985082913116]
# [0.44122748688504143, -0.33087015189408764, 2.43077118700778, -0.2520921296030769, 0.10960984157818278]
还有一些事情需要记住,您不能将一个方法发送到另一个进程。实际上,您要做的是发送整个实例,然后在该实例上调用该方法。我建议将分布式函数编写为带有显式参数的顶级函数,这样就可以清除进程之间传输的内容。它将有助于调试:)
最后,我强烈建议大家看看multiprocessing.Pool
及其map
方法,尤其是map\u async
和imap\u unordered
。如果您可以将工作负载表示为具有显式返回的函数,而不是共享对象上的有状态操作,那么从长远来看,编写代码和提高性能都会更容易。您是否与charmpy有任何关联?此外,这也不会提供可用的(我指的是其他任何人)回答你的问题。第一个问题:我与CharmPy或开发实验室无关。第二个问题:如果实例方法不能并行执行,并且所有实例方法的结果都可以很容易地接收到,这可能是有用的。这就是我的意图。听起来你好像忘记了每个进程只能有一个副本,而不是对实例的实际引用。什么是param,为什么你的实例化不在理解中?看起来你是在跳越荒谬的圈套来获得一个微不足道的结果。谢谢@Mad Physicastparam
是我传递给实例方法的参数。我无法思考,除了语法优雅之外,为什么应该使用理解而不是我正在使用的东西。一、 在网上冲浪和阅读之后,了解到子进程只复制类,因此将结果从孩子发送回家长,至少对我来说,这并不是小事,因为我是一个初学者。如果您能告诉我如何解决这个问题,我将不胜感激。obj_l=[范围(5)内的测试(0.2)]
。列表(string.ascii\u大写)[:5]
的整个业务是什么?你不需要跳过十个环来循环五次。一个普通的for循环也可以。谢谢你@Bi Rico's。我认为需要注意的是,`不能将方法发送到另一个进程'。正如正确指出的那样,我正在发送实例并对实例进行方法调用。我尝试过修改后的代码,它返回一个结果列表。我想要的是:既然我正在发送实例,并且有方法调用实例,那么我不会得到列表的列表或者列表的实例数的倍吗?如果我的理解有误,请纠正我。@RussellB对不起,我不太明白你的问题。我相信,如果将manager().list()
替换为[]
,将func1
远程调用替换为func1
本地调用,您得到的结果与您得到的结果相同,您是否期望有所不同?我的问题是:对于多个实例,我期望每个实例返回一个唯一的随机数列表。在重新阅读您的答案之后,我认为我应该将分布式函数作为顶级“函数”而不是类方法来编写,以避免此类问题。如果我的理解有误,请纠正我。我感谢你帮助我理解这一点的努力,我相信你的期望,“每个实例返回一个唯一的随机数列表”正是正在发生的事情。obj_l
中的每个实例都有不同的列表,当我们打印这些列表时,它们的长度不同,内容也不同。