python - 进程池执行器 : member variable lost in returned objects

标签 python parallel-processing multiprocessing future python-multiprocessing

我有一个基于 defaultdict 的类,它还有一个成员变量是 defaultdict (我的猜测:这就是问题所在?):

from collections import defaultdict
class A(defaultdict):
  def __init__(self):
    super(A, self).__init__(int)
    self.B = defaultdict(int)

  def methodA(self, id):
    # update values in self.B and self[key], for example:
    # self[id] = 1000
    # self[1] = 1
    # self.B[id] = 2000
    # self.B[2] = 2

  def get_B(self):
    return self.B.iteritems()
  def get_dict(self):
    return self.iteritems()

我正在使用 concurrent.futures 创建 A 的不同实例,如下所示:

from concurrent.futures import ProcessPoolExecutor, as_completed

futures = []
num_processes = 2 #some integer value

def process_parallel(id):
  A_1 = A()
  A_1.methodA(id)
  return A_1

with ProcessPoolExecutor() as exec:
  for p in range(num_processes):
    futures.append(exec.submit(process_parallel, p))

for f in as_completed(futures):
  A_instance = f.result()
  # iterate over A_instance.get_dict() and A_instance.get_B
  # A_instance[1] can be accessed, but A_instance.B is empty

问题是在 future 完成并返回结果后,B 成员变量不包含任何内容。为了进行检查,我确保 B 不是空的,甚至可以在 methodA 末尾打印其元素,但是一旦回到主进程,突然 B 似乎消失了。

B应该单独初始化吗?这样做的正确方法是什么?

最佳答案

我认为这里发生的情况是 ProcessPoolExecutor 正在使用 pickle序列化和反序列化您的类实例,并且作为实例的“B”属性的 defaultdict 的内容不会保留。

您可以通过在解释器中创建和更新类的实例、对它们进行酸洗和取消酸洗并检查结果来验证这一点。

如果您创建一个容器类来保存两个默认字典,它们都会在酸洗中幸存下来并且内容完好无损,所以这可能是最好的方法。例如(假设python3):

class A:

    def __init__(self):
        self.foo = defaultdict(int)
        self.bar = defaultdict(int)

    def baz(self, value):
        # update defaultdicts

关于python - 进程池执行器 : member variable lost in returned objects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35918500/

相关文章:

python - 选定行的性能,其中条件是与集合的匹配百分比

python 多处理和核心数量

python - Errno 32 multiprocessing.Queue 出现管道损坏错误

python - 为什么可以在 Python 函数中使用超过 2 ^ 16 个常量?

python - 如何使用 Python 导入正确调用 jsonnet

python - 在表单 django-allauth app 的末尾显示 google recaptcha

python - 调用后python中的声明函数

multithreading - 如何并行运行 Scalaz 任务

bash - 如何在 Bash 中并行运行给定函数?

python - 在装饰器内部使用多处理会产生错误 : can't pickle function. ..找不到