Python中for循环中的Mutliprocessing并传递多个参数
我正在用python脚本进行大量计算。由于受CPU限制,我通常使用线程模块的方法并没有产生任何性能改进 我现在尝试使用多处理而不是多线程来更好地使用我的CPU并加速冗长的计算 我在stackoverflow上找到了一些示例代码,但是我没有让脚本接受多个参数。有人能帮我解决这个问题吗?我以前从未使用过这些模块,我敢肯定我用错了Pool.map。-感谢您的帮助。其他实现多处理的方法也很受欢迎Python中for循环中的Mutliprocessing并传递多个参数,python,multithreading,python-3.x,python-multiprocessing,Python,Multithreading,Python 3.x,Python Multiprocessing,我正在用python脚本进行大量计算。由于受CPU限制,我通常使用线程模块的方法并没有产生任何性能改进 我现在尝试使用多处理而不是多线程来更好地使用我的CPU并加速冗长的计算 我在stackoverflow上找到了一些示例代码,但是我没有让脚本接受多个参数。有人能帮我解决这个问题吗?我以前从未使用过这些模块,我敢肯定我用错了Pool.map。-感谢您的帮助。其他实现多处理的方法也很受欢迎 from multiprocessing import Pool def calculation(foo,
from multiprocessing import Pool
def calculation(foo, bar, foobar, baz):
# Do a lot of calculations based on the variables
# Later the result is written to a file.
result = foo * bar * foobar * baz
print(result)
if __name__ == '__main__':
for foo in range(3):
for bar in range(5):
for baz in range(4):
for foobar in range(10):
Pool.map(calculation, foo, bar, foobar, baz)
Pool.close()
Pool.join()
正如你所怀疑的,你在多个方面使用了错误的方法
的要点是对iterable的所有元素调用函数。就像内置函数一样,但是是并行的。如果你想让一个电话排队,只需使用map
- 对于您特别询问的问题:
采用单参数函数。如果要传递多个参数,可以修改或包装函数,使其采用单个元组而不是多个参数(我将在末尾显示),或者只使用。或者,如果您想使用map
,则它将接受多个参数的函数,但传递的是参数元组,而不是单独的参数apply\u async
- 您需要在
实例上调用Pool
,而不是map
类。您试图做的类似于尝试从文件类型中读取Pool
,而不是从特定打开的文件中读取
- 每次迭代后,您都试图关闭并加入
池。在完成所有操作之前,您不希望这样做,否则您的代码将只等待第一个操作完成,然后为第二个操作引发异常
因此,最小的变化是:
if __name__ == '__main__':
pool = Pool()
for foo in range(3):
for bar in range(5):
for baz in range(4):
for foobar in range(10):
pool.apply_async(calculation, (foo, bar, foobar, baz))
pool.close()
pool.join()
请注意,我将所有内容都保存在if\uuuuuu name\uuuuuu='\uuuu main\uuuuuu':
块中,包括新的池()
构造函数。我不会在后面的例子中说明这一点,但这对于所有这些例子都是必要的,原因在文档的一节中解释。1
如果您想使用一个
map
函数,则需要一个充满参数的iterable,如下所示:
pool = Pool()
args = ((foo, bar, foobar, baz)
for foo in range(3)
for bar in range(5)
for baz in range(4)
for foobar in range(10))
pool.starmap(calculation, args)
pool.close()
pool.join()
或者,更简单地说:
pool = Pool()
pool.starmap(calculate, itertools.product(range(3), range(5), range(4), range(10)))
pool.close()
pool.join()
假设您没有使用旧版本的Python,您可以在with
语句中使用Pool
进一步简化它:
with Pool() as pool:
pool.starmap(calculate,
itertools.product(range(3), range(5), range(4), range(10)))
使用
map
或starmap
的一个问题是,它会做额外的工作来确保结果按顺序返回。但是您只是返回None
并忽略它,那么为什么这样做有效呢
使用apply\u async
没有这个问题
您也可以将map
替换为imap\u unordered
,但是没有istarmap\u unordered
,因此您需要将函数包装为不需要starmap
:
def starcalculate(args):
return calculate(*args)
with Pool() as pool:
pool.imap_unordered(starcalculate,
itertools.product(range(3), range(5), range(4), range(10)))
一,。如果您使用的是
spawn
或forkserver
启动方法,并且spawn
是Windows上的默认值,则每个子进程执行的操作相当于导入模块。因此,所有未受\uuuuu main\uuuu
保护的顶级代码将在每个子级中运行。该模块试图保护您免受由此带来的一些最坏后果的影响(例如,您经常会遇到一个异常,而不是以指数级的子级爆炸来创建新的子级),但它无法使代码实际工作。正如您所怀疑的,您在多个方面使用错误
的要点是对iterable的所有元素调用函数。就像内置函数一样,但是是并行的。如果你想让一个电话排队,只需使用map
- 对于您特别询问的问题:
采用单参数函数。如果要传递多个参数,可以修改或包装函数,使其采用单个元组而不是多个参数(我将在末尾显示),或者只使用。或者,如果您想使用map
,它接受多个参数的函数,但您传递的是apply\u async
参数元组,而不是单独的参数apply\u async
- 您需要在
实例上调用Pool
,而不是map
类。您试图做的类似于尝试从文件类型中读取Pool
,而不是从特定打开的文件中读取
- 每次迭代后,您都试图关闭并加入
池。在完成所有操作之前,您不希望这样做,否则您的代码将只等待第一个操作完成,然后为第二个操作引发异常
因此,最小的变化是:
if __name__ == '__main__':
pool = Pool()
for foo in range(3):
for bar in range(5):
for baz in range(4):
for foobar in range(10):
pool.apply_async(calculation, (foo, bar, foobar, baz))
pool.close()
pool.join()
请注意,我将所有内容都保存在if\uuuuuu name\uuuuuu='\uuuu main\uuuuuu':
块中,包括新的池()
构造函数。我不会在后面的例子中说明这一点,但这对于所有这些例子都是必要的,原因在文档的一节中解释。1
如果您想使用一个
map
函数,则需要一个充满参数的iterable,如下所示:
pool = Pool()
args = ((foo, bar, foobar, baz)
for foo in range(3)
for bar in range(5)
for baz in range(4)
for foobar in range(10))
pool.starmap(calculation, args)
pool.close()
pool.join()
或者,更简单地说:
pool = Pool()
pool.starmap(calculate, itertools.product(range(3), range(5), range(4), range(10)))
pool.close()
pool.join()
假设您没有使用旧版本的Python,您可以在with
语句中使用Pool
进一步简化它:
with Pool() as pool:
pool.starmap(calculate,
itertools.product(range(3), range(5), range(4), range(10)))
使用
map
或starmap
的一个问题是,它会做额外的工作来确保结果按顺序返回。但是您只是返回None
并忽略它,那么为什么这样做有效呢
使用apply\u async
没有这个问题
您也可以将map
替换为imap\u unordered
,但是没有istarmap\u unordered
,因此您需要将函数包装为not nee