Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中for循环中的Mutliprocessing并传递多个参数_Python_Multithreading_Python 3.x_Python Multiprocessing - Fatal编程技术网

Python中for循环中的Mutliprocessing并传递多个参数

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,

我正在用python脚本进行大量计算。由于受CPU限制,我通常使用线程模块的方法并没有产生任何性能改进

我现在尝试使用多处理而不是多线程来更好地使用我的CPU并加速冗长的计算

我在stackoverflow上找到了一些示例代码,但是我没有让脚本接受多个参数。有人能帮我解决这个问题吗?我以前从未使用过这些模块,我敢肯定我用错了Pool.map。-感谢您的帮助。其他实现多处理的方法也很受欢迎

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()

正如你所怀疑的,你在多个方面使用了错误的方法

  • map
    的要点是对iterable的所有元素调用函数。就像内置函数一样,但是是并行的。如果你想让一个电话排队,只需使用

  • 对于您特别询问的问题:
    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
保护的顶级代码将在每个子级中运行。该模块试图保护您免受由此带来的一些最坏后果的影响(例如,您经常会遇到一个异常,而不是以指数级的子级爆炸来创建新的子级),但它无法使代码实际工作。

正如您所怀疑的,您在多个方面使用错误

  • map
    的要点是对iterable的所有元素调用函数。就像内置函数一样,但是是并行的。如果你想让一个电话排队,只需使用

  • 对于您特别询问的问题:
    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