代码之家  ›  专栏  ›  技术社区  ›  Bussller Junior Vieira

并行执行实例方法[P]前:多处理-实例变量[覆盖]

  •  -1
  • Bussller Junior Vieira  · 技术社区  · 6 年前

    蟒蛇学家,

    这是我的类定义,

    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_come . 我对所有的物体都得到了相同的结果。看起来像是, 你自己出来吧

    编辑-1:

    multiprocessing.Manager.list() . 想办法得到这份工作。非常感谢您的帮助。

    编辑-2:

    只是访问 你自己出来吧 实例 Test 你自己出来吧 实例。

    我尝试了另一种使用 Threading 你自己出来吧 分开处理。然而,我没有得到任何加速(由于吉尔)。本质上,是串行运行而没有任何并行化。

    我试过使用 multiprocessing.Queue

    还有其他建议/想法吗?(努巴或赛顿)

    2 回复  |  直到 6 年前
        1
  •  2
  •   Bi Rico    6 年前

    我认为您看到的问题是,您的所有进程共享同一个随机种子,如果我修复代码中的错误并向分布式函数添加一个随机种子,那么一切似乎都正常。试着用下面的随机种子来注释这行,然后再运行一次。

    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_async imap_unordered . 如果您可以将工作负载表示为具有显式返回的函数,而不是共享对象上的有状态操作,那么从长远来看,编写代码和提高性能都会更容易。

        2
  •  -1
  •   Bussller Junior Vieira    6 年前

    为了完成,将此作为答案发布:

    对于那些希望并行执行实例方法(如果不是不可能的话)的人来说,Python似乎很难做到这一点。

    CharmPy . 而这要求所有类都是 Chare 父类,这是可以实现的。

    Charm++