python - 类方法的并行执行

标签 python multiprocessing

我需要并行执行同一类的许多实例的方法。为此,我尝试使用 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中每个实例变量的自己的单独副本。因此,您对子级所做的更改不会反射(reflect)在父级中。您需要通过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 代理实例。这样,您在子级中所做的更改将自动反射(reflect)在父级中。但这是以增加使用父级变量的开销为代价的。

这是一个使用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]

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

关于python - 类方法的并行执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26239695/

相关文章:

python - 通过 "for"循环(即 "for x in list:")访问列表时,有没有办法在同一循环中访问列表中的 "x+1"项?

python - Spyder-IDE 如何打开参数检查

Python 正则表达式 字符之间的匹配

python - Python中的并行递归函数

python - 为什么我没有看到通过 Python 中的多处理加速?

python - 多处理写入 Pandas 数据框

python - 使用 pandas 返回 hdf 文件中所有数据集的列表

python - 将附加列添加到 panda 数据框中比较两列

python - 跨多个进程训练模型时,在 PyTorch 中使用 tensor.share_memory_() 与 multiprocessing.Queue

Windows : AttributeError: Can't get attribute "abc" 上 Jupyter 中的 python 多处理