python多处理:为每个工作者提供一个特定的参数

2024-05-13 19:10:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Pool个worker,并希望每个worker都使用一个特定的对象进行初始化。更准确地说,初始化不能并行化,因此我计划在创建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 出于好奇,我仍然对答案感兴趣


Tags: the对象importselfobjectfooparammain
1条回答
网友
1楼 · 发布于 2024-05-13 19:10:51

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

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

相关问题 更多 >