【问题标题】:multiprocessing.Pool, does not affect the classes variables permanentlymultiprocessing.Pool,不会永久影响类变量
【发布时间】:2015-09-09 13:08:16
【问题描述】:

我正在使用 multiprocessing.Pool 将方法的工作分配到多个处理器上。当我向字典添加内容时,执行该方法后它会丢失。这是为什么?以及如何规避它?

from multiprocessing import Pool


class Agent:
    def __init__(self):
        self.test_dict = {}

    def apply(self, num):
        # something very processor intensive here
        self.test_dict[num] = num
        print 'inside ', self.test_dict

def F(x):
    agent, i = x
    return agent.apply(i)

class SeriesInstance(object):
    def __init__(self):
        self.agent = Agent()
        self.F = F

    def run(self):
        p = Pool()

        for i in range(5):
            out = p.map(F, [(self.agent, i),])

            print 'outside', self.agent.test_dict


        p.close()
        p.join()

        return out

if __name__ == '__main__':
    SeriesInstance().run()

输出是这样,但是外面应该等于里面

inside  {0: 0}
outside {}
inside  {1: 1}
outside {}
inside  {2: 2}
outside {}
inside  {3: 3}
outside {}
inside  {4: 4}
outside {}

【问题讨论】:

标签: python python-multiprocessing


【解决方案1】:

请检查Sharing state between processes 并阅读服务器进程部分。看来您必须创建一个管理器并使用该管理器来创建您的 Agent 类中使用的 dict 实例。

from multiprocessing import Process, Manager

def f(d, l):
    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.reverse()

if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict()
        l = manager.list(range(10))

        p = Process(target=f, args=(d, l))
        p.start()
        p.join()

        print(d)
        print(l)

【讨论】:

    【解决方案2】:

    Noctis-Skytower 有一个解决方案,但更一般的答案是,除非有充分的理由,否则不应尝试在进程之间共享状态。

    要了解这种行为的原因,请查看this answer 的类似问题。当您在另一个进程中更改对象时,实际上是在更改该对象的 副本。 IE。您的对象会在子进程中重新创建,而不是直接使用。

    在文档here 中,您可以看到您基本上希望传递简单的消息而不是沉重的对象。这可能意味着您需要重新设计工作流程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      相关资源
      最近更新 更多