我正在使用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
出于好奇,我仍然对答案感兴趣
正如您所说,您可以看到
Foo
的实例对于每个工作者实际上是不同的,即使它们显然具有相同的地址正如对this question和this question的回答中所解释的,您不应该依赖地址来区分不同进程上的实例:不同的实例可以显示相同的地址
相关问题 更多 >
编程相关推荐