gpt4 book ai didi

python - 使用初始化启动 concurrent.futures.ProcessPoolExecutor?

转载 作者:太空狗 更新时间:2023-10-29 23:58:29 36 4
gpt4 key购买 nike

我打算使用 concurrent.futures.ProcessPoolExecutor 来并行执行函数。根据documentation ,它的executor对象只能接受map中的一个简单函数。我的实际情况涉及在执行“待并行化”功能之前进行初始化(加载数据)。我该如何安排?

'to-be-parallelized'函数在一个迭代中被多次调用。我不希望它每次都重新初始化。

换句话说,有一个 init 函数可以为这个 tbp 函数产生一些输出。每个 child 都应该有自己的输出副本,因为函数依赖于它。

最佳答案

如果使用 Python 3.7 或更高版本,请使用 RuRo's answer below 。此答案仅与 concurrent.futures 不支持传递 initializer 函数的早期 Python 版本相关。


听起来您正在寻找与 multiprocessing.Pool 采用的 initializer/initargs 选项等效的选项。目前,concurrent.futures.ProcessPoolExecutor 不存在该行为,但有一个 patch waiting for review 添加了该行为。

因此,您可以使用 multiprocessing.Pool(这可能适合您的用例),等待该补丁合并并发布(您可能需要等待一段时间 :)),或者推出自己的解决方案。事实证明,为带有 initializer 的 map 编写一个包装函数并不太难,但每个进程只调用它一个:

from concurrent.futures import ProcessPoolExecutor
from functools import partial

inited = False
initresult = None

def initwrapper(initfunc, initargs, f, x):
# This will be called in the child. inited
# Will be False the first time its called, but then
# remain True every other time its called in a given
# worker process.
global inited, initresult
if not inited:
inited = True
initresult = initfunc(*initargs)
return f(x)

def do_init(a,b):
print('ran init {} {}'.format(a,b))
return os.getpid() # Just to demonstrate it will be unique per process

def f(x):
print("Hey there {}".format(x))
print('initresult is {}'.format(initresult))
return x+1

def initmap(executor, initializer, initargs, f, it):
return executor.map(partial(initwrapper, initializer, initargs, f), it)


if __name__ == "__main__":
with ProcessPoolExecutor(4) as executor:
out = initmap(executor, do_init, (5,6), f, range(10))
print(list(out))

输出:

ran init 5 6
Hey there 0
initresult is 4568
ran init 5 6
Hey there 1
initresult is 4569
ran init 5 6
Hey there 2
initresult is 4570
Hey there 3
initresult is 4569
Hey there 4
initresult is 4568
ran init 5 6
Hey there 5
initresult is 4571
Hey there 6
initresult is 4570
Hey there 7
initresult is 4569
Hey there 8
initresult is 4568
Hey there 9
initresult is 4570
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

关于python - 使用初始化启动 concurrent.futures.ProcessPoolExecutor?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32130990/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com