当前位置: 首页 > 面试题库 >

Python-multiprocessing.Pool:何时使用apply,apply_async或map?

邹齐智
2023-03-14
问题内容

我还没有看到关于Pool.applyPool.apply_asyncPool.map用例的清晰示例。我主要使用Pool.map; 别人的优势是什么?


问题答案:

在Python的早期,要使用任意参数调用函数,可以使用apply

apply(f,args,kwargs)

apply在Python2.7中仍然存在,尽管在Python3中却不存在,并且通常不再使用。如今,

f(*args,**kwargs)

是首选。这些multiprocessing.Pool模块尝试提供类似的接口。

Pool.apply就像Python一样apply,除了函数调用是在单独的进程中执行的。Pool.apply直到功能完成为止。

Pool.apply_async也类似于Python的内置函数apply,区别在于调用立即返回而不是等待结果。AsyncResult返回一个对象。你调用其get()方法以检索函数调用的结果。该get()方法将阻塞直到功能完成。因此,pool.apply(func, args, kwargs)等效于pool.apply_async(func, args, kwargs).get()

与相比Pool.apply,该Pool.apply_async方法还具有一个回调(如果提供),则在函数完成时调用该回调。可以使用它来代替get()

例如:

import multiprocessing as mp
import time

def foo_pool(x):
    time.sleep(2)
    return x*x

result_list = []
def log_result(result):
    # This is called whenever foo_pool(i) returns a result.
    # result_list is modified only by the main process, not the pool workers.
    result_list.append(result)

def apply_async_with_callback():
    pool = mp.Pool()
    for i in range(10):
        pool.apply_async(foo_pool, args = (i, ), callback = log_result)
    pool.close()
    pool.join()
    print(result_list)

if __name__ == '__main__':
    apply_async_with_callback()

可能会产生如下结果

[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]

请注意,与不同pool.map,结果的顺序可能与pool.apply_async调用的顺序不同。

因此,如果你需要在一个单独的进程中运行一个函数,但是希望当前进程在该函数返回之前一直阻塞,请使用Pool.apply。像一样Pool.applyPool.map阻塞直到返回完整的结果。

如果你希望工作进程池异步执行许多功能调用,请使用Pool.apply_async。结果的顺序不能保证与调用的顺序相同Pool.apply_async

还要注意,你可以使用调用许多不同的函数Pool.apply_async(并非所有调用都需要使用同一函数)。

相反,Pool.map将相同的函数应用于许多参数。但是,与不同Pool.apply_async,返回结果的顺序与参数的顺序相对应。



 类似资料:
  • 问题内容: 我有一个脚本,其中包括从列表中打开文件,然后对该文件中的文本进行处理。我正在使用python multiprocessing和Pool尝试并行化此操作。脚本的抽象如下: 运行此命令时,每次迭代的进程ID的打印均相同。基本上,我想做的是获取输入列表中的每个元素并将其分叉到一个单独的进程中,但是似乎一个进程正在完成所有工作。 问题答案: 将一项任务分配到池中。您将需要多次调用 才能使用更多

  • 问题内容: 我试图了解表运算符。 这是示例: 我的主要障碍是了解 何时 使用。 所以我想知道使用in实现的结果与上述相同将有多困难? 是否会使查询更短或更易读? 如果该示例没有显示使用的巨大优势,那么什么是使用显着的优势呢? 问题答案: 首先-可以调用 表值函数 ,其中参数值是从查询的表中获取的,如下所示: 或 切碎xml列 根据我的经验,当您需要进行一些 预先计算 时,它非常有用: 使用的另一个

  • 问题内容: 我想限制子进程中的资源访问。例如-限制 http下载量 , disk io 等。如何扩展基本代码来实现它? 请分享一些基本的代码示例。 问题答案: 创建池时,请使用initializer和initargs参数,以便在所有子进程中定义全局变量。 例如: 该代码将按升序(提交作业的顺序)打印数字0-3,因为它使用了锁。注释掉该行以查看它以降序打印出数字。 此解决方案在Windows和UNI

  • 问题内容: 我已经看到许多有关使用方法的堆栈溢出问题的答案。我还看到用户在他们的评论下说“ apply很慢,应该避免”。 我已经阅读了许多有关性能的文章,这些文章解释得很慢。我还在文档中看到了关于免除apply传递UDF的便捷功能的免责声明(现在似乎找不到)。因此,普遍的共识是,应尽可能避免。但是,这引起了以下问题: 如果apply太糟糕了,那为什么在API中呢? 我应该如何以及何时使代码免费?