python 多处理: setting class attribute value

标签 python multiprocessing

我有一个名为 Experiment 的类和另一个名为 Case 的类。一个实验由许多个案组成。请参阅下面的类定义,

from multiprocessing import Process

class Experiment (object):
    def __init__(self, name):
        self.name = name
        self.cases = []
        self.cases.append(Case('a'))
        self.cases.append(Case('b'))
        self.cases.append(Case('c'))

    def sr_execute(self):
        for c in self.cases:  
            c.setVars(6)

class Case(object):
    def __init__(self, name):
        self.name = name
    def setVars(self, var):
        self.var = var

在我的实验课上,我有一个叫做 sr_execute 的函数。此函数显示所需的行为。我有兴趣解析所有案例并为每个案例设置一个属性。当我运行以下代码时,

if __name__ == '__main__':
    #multiprocessing.freeze_support()
    e = Experiment('exp')
    e.sr_execute()
    for c in e.cases: print c.name, c.var

我明白了,

a 6
b 6
c 6

这是期望的行为。

但是,我想使用多处理并行执行此操作。为此,我向实验类添加了一个 mp_execute() 函数,

    def mp_execute(self):
        processes = []
        for c in self.cases: 
            processes.append(Process(target= c.setVars, args = (6,)))
        [p.start() for p in processes]
        [p.join() for p in processes]

但是,这不起作用。当我执行以下命令时,

if __name__ == '__main__':
    #multiprocessing.freeze_support()
    e = Experiment('exp')
    e.mp_execute()
    for c in e.cases: print c.name, c.var

我得到一个错误,

AttributeError: 'Case' object has no attribute 'var'

显然,我无法使用多处理设置类属性。

任何线索是怎么回事,

最佳答案

当你打电话时:

def mp_execute(self):
    processes = []
    for c in self.cases: 
        processes.append(Process(target= c.setVars, args = (6,)))
    [p.start() for p in processes]
    [p.join() for p in processes]

当您创建 Process 时,它将使用您的对象的副本,并且对此类对象的修改不会传递给主程序因为不同的进程有不同的地址空间。如果你使用 Thread 就可以了 因为在那种情况下不会创建副本。

另请注意,您的代码在 Windows 中可能会失败,因为您将方法作为 target 传递,而 Windows 要求 target 是可挑选的(并且实例方法是 不可挑选)。 target 应该是在模块顶层定义的函数,以便在所有 Oses 上工作。

如果您想将更改传达给主流程,您可以:

无论如何,您必须通过设置“ channel ”(如队列)或设置共享状态来“显式”处理通信。


风格说明:不要以这种方式使用列表解析:

[p.join() for p in processes]

这完全是错误的。创建None 列表只是在浪费空间。与正确的方式相比,它也可能更慢:

for p in processes:
    p.join()

因为它必须将元素追加到列表中。

有人说列表理解比 for 循环稍微快一些,但是:

  • 性能差异非常小,通常无关紧要
  • 它们更快当且仅当您考虑这种循环:

    a = []
    for element in something:
        a.append(element)
    

    如果像本例一样,循环创建列表,那么for 循环会更快。

顺便说一句:有些人以同样的方式使用map来执行副作用。这又是错误的,因为与之前相同的原因,您不会获得太多速度并且它在python3 中完全失败,其中map 返回一个迭代器并且因此它根本执行函数,从而使代码的可移植性降低。

关于 python 多处理: setting class attribute value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19828612/

相关文章:

python - 在多处理中创建 Singleton 类

node.js - 当我启动新进程时,NodeJS fork 进程会减慢所有其他 fork 进程的速度

python - 如何将 NumPy 数组转换为应用 matplotlib 颜色图的 PIL 图像

php - PHP 中带有参数的 Python 脚本

python - 修改 `locals()` 或 `frame.f_locals` 中的*现有*变量

Python 多线程和多处理加速循环

python - 让 SQLite3 与多线程一起工作

python - 如何使用 Gtk.events_pending?

python - 在 python pandas 中将多个年份列转换为单个年份列(整洁格式)

python - 如何使进程能够写入主程序的数组?