Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 并行执行实例方法[以前:多处理-实例变量得到覆盖]_Python_Python 3.x_Multiprocessing - Fatal编程技术网

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 Physicast
param
是我传递给实例方法的参数。我无法思考,除了语法优雅之外,为什么应该使用理解而不是我正在使用的东西。一、 在网上冲浪和阅读之后,了解到子进程只复制类,因此将结果从孩子发送回家长,至少对我来说,这并不是小事,因为我是一个初学者。如果您能告诉我如何解决这个问题,我将不胜感激。
obj_l=[范围(5)内的测试(0.2)]
列表(string.ascii\u大写)[:5]
的整个业务是什么?你不需要跳过十个环来循环五次。一个普通的for循环也可以。谢谢你@Bi Rico's。我认为需要注意的是,`不能将方法发送到另一个进程'。正如正确指出的那样,我正在发送实例并对实例进行方法调用。我尝试过修改后的代码,它返回一个结果列表。我想要的是:既然我正在发送实例,并且有方法调用实例,那么我不会得到列表的列表或者列表的实例数的倍吗?如果我的理解有误,请纠正我。@RussellB对不起,我不太明白你的问题。我相信,如果将
manager().list()
替换为
[]
,将
func1
远程调用替换为
func1
本地调用,您得到的结果与您得到的结果相同,您是否期望有所不同?我的问题是:对于多个实例,我期望每个实例返回一个唯一的随机数列表。在重新阅读您的答案之后,我认为我应该将分布式函数作为顶级“函数”而不是类方法来编写,以避免此类问题。如果我的理解有误,请纠正我。我感谢你帮助我理解这一点的努力,我相信你的期望,“每个实例返回一个唯一的随机数列表”正是正在发生的事情。
obj_l
中的每个实例都有不同的列表,当我们打印这些列表时,它们的长度不同,内容也不同。