并行执行类方法

Jan*_*wda 2 python multiprocessing

我需要并行执行同一个类的许多实例的方法.为此,我正在尝试使用模块中Process.start()Process.join()命令multiprocessing.

例如,对于一个类:

class test:
     def __init__(self):
     ...
     ...
     def method(self):
     ...
     ...
Run Code Online (Sandbox Code Playgroud)

其中method修改了一些类变量.如果我创建了两个类的实例:

t1=test()
t2=test()
Run Code Online (Sandbox Code Playgroud)

并执行:

from multiprocessing import Process
pr1=Process(target=t1.method, args=(,))
pr2=Process(target=t2.method, args=(,))
pr1.start()
pr2.start()
pr1.join()
pr2.join()
Run Code Online (Sandbox Code Playgroud)

类的实例的变量没有更新(整个代码太长了,不能粘贴在这里,但这是个主意).

有没有办法实现这个目标?谢谢

dan*_*ano 12

当您调用obj.method子进程时,子进程将获得每个实例变量的单独副本obj.因此,您在孩子中对他们所做的更改不会反映在父级中.您需要通过a显式地将更改的值传递回父multiprocessing.Queue级,以使更改对父级生效:

from multiprocessing import Process, Queue
q1 = Queue()
q2 = Queue()
pr1 = Process(target=t1.method, args=(q1,))
pr2 = Process(target=t2.method, args=(q2,))
pr1.start()
pr2.start()
out1 = q1.get()
out2 = q2.get()
t1.blah = out1
t2.blah = out2
pr1.join()
pr2.join()
Run Code Online (Sandbox Code Playgroud)

其他选项是使您需要更改multiprocessing.Value实例或实例的实例变量.这样,您在子项中所做的更改自动反映在父项中.但这是以增加在父级中使用变量的开销为代价的.multiprocessing.Manager Proxy

这是一个使用的例子multiprocessing.Manager.这不起作用:

import multiprocessing

class Test(object) :

    def __init__(self):
       self.some_list = []  # Normal list

    def method(self):
        self.some_list.append(123)  # This change gets lost


if __name__ == "__main__":
    t1 = Test()
    t2 = Test()
    pr1 = multiprocessing.Process(target=t1.method)
    pr2 = multiprocessing.Process(target=t2.method)
    pr1.start()
    pr2.start()
    pr1.join()
    pr2.join()
    print(t1.some_list)
    print(t2.some_list)
Run Code Online (Sandbox Code Playgroud)

输出:

[]
[]
Run Code Online (Sandbox Code Playgroud)

这有效:

import multiprocessing

class Test(object) :

    def __init__(self):
       self.manager = multiprocessing.Manager()
       self.some_list = self.manager.list()  # Shared Proxy to a list

    def method(self):
        self.some_list.append(123) # This change won't be lost


if __name__ == "__main__":
    t1 = Test()
    t2 = Test()
    pr1 = multiprocessing.Process(target=t1.method)
    pr2 = multiprocessing.Process(target=t2.method)
    pr1.start()
    pr2.start()
    pr1.join()
    pr2.join()
    print(t1.some_list)
    print(t2.some_list)
Run Code Online (Sandbox Code Playgroud)

输出:

[123]
[123]
Run Code Online (Sandbox Code Playgroud)

请记住,multiprocessing.Manager启动子进程来管理您创建的所有共享实例,并且每次访问其中一个Proxy实例时,您实际上都在对该Manager进程进行IPC调用.