并行执行类方法
问题内容:
我需要并行执行同一类的许多实例的方法。为此,我尝试使用来自模块的Process.start()
和Process.join()
命令multiprocessing
。
例如一个班级:
class test:
def __init__(self):
...
...
def method(self):
...
...
在哪里method
修改一些类变量。如果我创建了该类的两个实例:
t1=test()
t2=test()
并执行:
from multiprocessing import Process
pr1=Process(target=t1.method, args=(,))
pr2=Process(target=t2.method, args=(,))
pr1.start()
pr2.start()
pr1.join()
pr2.join()
该类实例的变量不会更新(整个代码太长了,无法粘贴到这里,但这是个主意)。
有什么办法可以做到这一点?谢谢
问题答案:
当您调用obj.method
子进程时,子进程将获得中每个实例变量的单独副本obj
。因此,您在子代中对它们所做的更改不会反映在父代中。您需要通过将更改的值显式地传递给父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()
其他选择是使实例变量成为更改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)
输出:
[]
[]
这有效:
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)
输出:
[123]
[123]
只需记住,a会multiprocessing.Manager
启动一个子进程来管理您创建的所有共享实例,并且每次访问一个Proxy
实例时,您实际上是在对该Manager
进程进行IPC调用。