Python多进程处理方法(Pool、apply_async、map_async)

由于Python的多线程并不能真正支持并行,实际上仍采用的是单核串行的方式,这与它的GIL(全局解释器锁)有关。因此,我们需要异步并行地执行某些程序时,可以采用多进程的方式。

多进程详细API可以参考链接:https://docs.python.org/zh-cn/3/library/multiprocessing.html,本文主要讲述其中的关键部分以及使用样例。

1、常用的进程池Pool类处理方法

1.1 apply(func[, args[, kwds]])

使用 args 参数以及 kwds 命名参数调用 func , 它会返回结果前阻塞。这种情况下,apply_async() 更适合并行化工作。另外 func 只会在一个进程池中的一个工作进程中执行。

1.2 apply_async(func[, args[, kwds[, callback[, error_callback]]]])

apply() 方法的一个变种,返回一个 AsyncResult 对象。

如果指定了 callback , 它必须是一个接受单个参数的可调用对象。当执行成功时, callback 会被用于处理执行后的返回结果,否则,调用 error_callback 。

如果指定了 error_callback , 它必须是一个接受单个参数的可调用对象。当目标函数执行失败时, 会将抛出的异常对象作为参数传递给 error_callback 执行。

回调函数应该立即执行完成,否则会阻塞负责处理结果的线程。

1.3 map(funciterable[, chunksize])

内置 map() 函数的并行版本 (但它只支持一个 iterable 参数,对于多个可迭代对象请参阅 starmap())。 它会保持阻塞直到获得结果。

这个方法会将可迭代对象分割为许多块,然后提交给进程池。可以将 chunksize 设置为一个正整数从而(近似)指定每个块的大小可以。

注意对于很长的迭代对象,可能消耗很多内存。可以考虑使用 imap() 或 imap_unordered() 并且显示指定 chunksize 以提升效率。

1.4 map_async(funciterable[, chunksize[, callback[, error_callback]]])

map() 方法的一个变种,返回一个 AsyncResult 对象。

如果指定了 callback , 它必须是一个接受单个参数的可调用对象。当执行成功时, callback 会被用于处理执行后的返回结果,否则,调用 error_callback 。

如果指定了 error_callback , 它必须是一个接受单个参数的可调用对象。当目标函数执行失败时, 会将抛出的异常对象作为参数传递给 error_callback 执行。

回调函数应该立即执行完成,否则会阻塞负责处理结果的线程。

2、异步进程返回结果 AsyncResult 处理方法

AsyncResult 为 Pool.apply_async() 和 Pool.map_async() 返回对象所属的类。

get([timeout])

用于获取执行结果。如果 timeout 不是 None 并且在 timeout 秒内仍然没有执行完得到结果,则抛出 multiprocessing.TimeoutError 异常。如果远程调用发生异常,这个异常会通过 get() 重新抛出。

wait([timeout])

阻塞,直到返回结果,或者 timeout 秒后超时。

ready()

返回执行状态,是否已经完成。

successful()

判断调用是否已经完成并且未引发异常。 如果还未获得结果则将引发 ValueError

在 3.7 版更改: 如果没有执行完,会抛出 ValueError  异常而不是 AssertionError 。

3、多进程处理样例

本例特点:可以异步执行,每个进程传入多个参数,并且完整获取到进程的多个返回值

from multiprocessing import Pool


def test(arg1, arg2):
    return "hello," + arg1, arg2 + ' test', [2222, 5, 356]


if __name__ == '__main__':
    p = Pool(2)
    results = []
    rslt1 = p.apply_async(test, ('world1', 'tea',))  # 异步执行进程1,传入两个参数
    results.append(rslt1)
    rslt2 = p.apply_async(test, ('world2', 'cat',))  # 异步执行进程2,传入两个参数
    results.append(rslt2)
    for r in results:
        a, b, c = r.get()  # 获取异步进程执行结果,返回值有三个
        print(a, b, c)

# 两个进程的结果输出分别为:
# hello,world1 tea test [2222, 5, 356]
# hello,world1 cat test [2222, 5, 356]

传多个参数推荐使用apply_async,如果采用map_async,无法通过p.map_async(test, ('world1', 'tea',))的方式传入多个参数 。

  • 7
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Python中的multiprocessing模块提供了多种处理多进程的方式,其中之一就是使用Pool类来创建进程池。 使用Pool类的步骤如下: 1. 首先导入multiprocessing模块中的Pool类: ```python from multiprocessing import Pool ``` 2. 创建Pool对象,指定进程池中的进程数: ```python pool = Pool(processes=4) # 进程池中有4个进程 ``` 3. 使用Pool对象的map方法调用需要多进程处理的函数: ```python results = pool.map(my_function, my_list) ``` 其中,my_function是需要处理的函数,my_list是需要处理的数据列表。map方法会将my_list中的每一个元素依次传递给my_function函数进行处理,并将处理结果保存在results列表中。 4. 最后记得关闭进程池: ```python pool.close() pool.join() ``` 这样就完成了使用Pool类进行多进程处理的操作。注意,在使用Pool类时,需要注意内存占用问题,尽量避免出现内存泄漏等问题。 ### 回答2: Python中的multiprocessing模块提供了一种使用进程来并行执行任务的方法。其中,Pool类是multiprocessing模块中的一个重要组件,用于创建并管理进程池。 使用Pool可以很方便地实现多进程并行执行任务,具体步骤如下: 1. 首先,导入multiprocessing模块中的Pool类:`from multiprocessing import Pool` 2. 创建一个Pool实例,指定进程数量,可以使用默认的进程数量(与CPU核心数相同)或者自己指定。例如,创建一个由4个进程组成的进程池:`pool = Pool(4)` 3. 使用进程池的map()方法来提交任务。map()方法可以接受一个函数和一个可迭代对象作为参数,然后将可迭代对象中的每个元素依次作为参数传递给函数,并发地执行这些任务。示例:`result = pool.map(func, iterable)` 4. 进程池会根据系统资源自动创建和管理子进程,将任务分配给这些子进程进行并发执行。执行完成后,会返回一个结果列表,其中每个元素是对应任务的返回值。 5. 随着任务的完成,进程池会自动回收并终止子进程,释放系统资源。需要注意的是,在使用完进程池后,需要调用close()和join()方法来等待子进程结束并清理资源。示例:`pool.close()`和`pool.join()` Python的multiprocessing模块中的Pool类提供了便捷的多进程管理功能,可以大大提高程序的执行效率。适用于任务间相互独立且计算密集型的应用场景。但当任务之间存在依赖关系或需要共享数据时,需要进一步考虑进程间通信和同步的问题。 ### 回答3: Python中的多进程模块`multiprocessing`中,`Pool`类是一个用于管理进程池的工具。它可以帮助我们并行执行多个任务,提高程序的运行效率。 `Pool`类的主要方法包括以下几个: 1. `__init__(self, processes=None, initializer=None, initargs=(), maxtasksperchild=None)`:初始化进程池,其中`processes`参数指定进程池中的进程数量,默认为CPU的核心数;`initializer`和`initargs`参数可以设置在每个子进程运行之前执行的初始化函数和它的参数;`maxtasksperchild`参数指定每个子进程完成多少个任务后再关闭并重新创建一个新的子进程。 2. `apply(func, args=(), kwds={})`:用于在进程池中同步地调用一个函数,并返回函数的执行结果,`args`和`kwds`是函数的参数。 3. `apply_async(func, args=(), kwds={}, callback=None)`:用于在进程池中异步地调用一个函数,返回一个`ApplyResult`对象,通过该对象的`get()`方法可以获取函数的执行结果。 4. `map(func, iterable, chunksize=None)`:将函数应用于可迭代对象中的每个元素,并返回执行结果的列表。如果指定了`chunksize`参数,则将可迭代对象分块处理。 5. `map_async(func, iterable, chunksize=None, callback=None)`:与`map()`方法类似,但是是异步地调用函数,返回一个`MapResult`对象。 6. `close()`:停止向进程池中添加新的任务。 7. `join()`:等待所有的子进程执行完毕。 通过使用`Pool`类,我们可以轻松地实现多个任务的并行执行,从而加快程序的运行速度。在使用时,需要注意合理设置进程数和合理利用`apply()`、`apply_async()`、`map()`等方法,根据任务的特点选择合适的调用方式,以达到最佳的性能和效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值