【问题标题】:python multiprocessing : provide one specific argument to each workerpython multiprocessing:为每个工作人员提供一个特定的参数
【发布时间】:2021-01-07 08:19:39
【问题描述】:

我正在使用Pool 的工人,并希望他们每个人都使用特定的对象进行初始化。更确切地说,初始化不能并行化,所以我打算在创建worker之前准备好主进程中的对象,并给每个worker一个这些对象。

这是我的尝试:

import multiprocessing
import random
import time

class Foo:
    def __init__(self, param):
        # NO WAY TO PARALLELIZE THIS !!
        print(f"Creating Foo with {param}")
        self.param = param

    def __call__(self, x):
        time.sleep(1)
        print("Do the computation", self)
        return self.param + str(x)

def initializer():
    global myfoo

    param = random.choice(["a", "b", "c", "d", "e"])
    myfoo = Foo(param)

def compute(x):
    return myfoo(x)

multiple_results = []
with multiprocessing.Pool(2, initializer, ()) as pool:
    for i in range(1, 10):
        work = pool.apply_async(compute, (i,))
        multiple_results.append(work)

    print([res.get(timeout=2) for res in multiple_results])

这是一个可能的输出:

Creating Foo with b
Creating Foo with a
Do the computation <__main__.Foo object at 0x7f8d70aa7fd0>
Do the computation <__main__.Foo object at 0x7f8d70aa7fd0>
Do the computation <__main__.Foo object at 0x7f8d70aa7fd0>
Do the computation <__main__.Foo object at 0x7f8d70aa7fd0>
Do the computation <__main__.Foo object at 0x7f8d70aa7fd0>
Do the computation <__main__.Foo object at 0x7f8d70aa7fd0>
Do the computation <__main__.Foo object at 0x7f8d70aa7fd0>
Do the computation <__main__.Foo object at 0x7f8d70aa7fd0>
Do the computation <__main__.Foo object at 0x7f8d70aa7fd0>
['b1', 'a2', 'b3', 'a4', 'b5', 'a6', 'b7', 'a8', 'b9']

让我感到困惑的是Foo 对象的地址始终相同,而实际的Foo 对象却不同,从输出中可以看出:"b1", "a2"

我的问题是对initializer 的两次调用是并行的,而我不想并行构造Foo

我想要一些神奇的方法add_worker 来做这样的事情:

pool = multiprocessing.Pool()
for i in range(0,2):
    foo = Foo()
    poo.add_worker(initializer, (foo,))

有什么想法吗?

编辑:我通过在进程内部而不是在文件顶部制作 kera 的 VGGNet 的import 解决了我真正的生活问题。见this answer 出于好奇,我仍然对答案感兴趣。

【问题讨论】:

  • 有趣。在 Windows 上,我得到两个单独的地址......也许这与两个系统之间的内存管理差异有关。也许在 Linux 上,地址是每个进程的内存区域,所以你得到相同的地址......
  • 这是一个有趣的问题,但我有一个问题。为什么会打扰你?只要结果没问题...
  • @Tomerikoo 因为初始化函数在并行化时没有完成。在我的真实生活环境中, Foo 对象创建了一个 kera.applications.vgg16;也许我应该提出一个具体问题“如何并行化 vgg16”?
  • 如果你想在每个工作人员中创建不同的实例,然后在compute中创建它们
  • @furas 如果您在compute 中创建Foo 的新实例,则compute 的每次执行都会有一个不同的Foo 实例,而不是每个worker。因此,如果您有 10 个调用 compute 和 2 个工作人员,您将有 10 个不同的 Foo 实例,而 @Laurent Clasessesns 似乎只需要其中两个(每个工作人员一个)。如果每次执行compute 都有一个不同的Foo 实例很好,那么您的方法是正确的。

标签: python python-3.x python-multiprocessing


【解决方案1】:

正如您所说,您可以看到 Foo 的实例对于每个工人来说实际上是不同的,即使它们显然具有相同的地址。

正如对this questionthis question 的回答中所述,您不应依赖地址来区分不同进程上的实例:不同的实例可以显示相同的地址。

【讨论】:

  • 我也在考虑地址。旧系统 CPU (Intel/AMD) 可以在进程中使用相对地址而不是绝对地址,而且看起来有点类似。
  • 感谢您的回答澄清了一点。但这并不能回答主要问题。
猜你喜欢
  • 1970-01-01
  • 2023-03-16
  • 2013-02-23
  • 1970-01-01
  • 2013-11-05
  • 1970-01-01
  • 2021-03-30
  • 2019-10-04
  • 1970-01-01
相关资源
最近更新 更多