Python多进程处理方法(Pool、apply | 您所在的位置:网站首页 › python过去当前路径 › Python多进程处理方法(Pool、apply |
由于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(func, iterable[, chunksize]) 内置 map() 函数的并行版本 (但它只支持一个 iterable 参数,对于多个可迭代对象请参阅 starmap())。 它会保持阻塞直到获得结果。 这个方法会将可迭代对象分割为许多块,然后提交给进程池。可以将 chunksize 设置为一个正整数从而(近似)指定每个块的大小可以。 注意对于很长的迭代对象,可能消耗很多内存。可以考虑使用 imap() 或 imap_unordered() 并且显示指定 chunksize 以提升效率。 1.4 map_async(func, iterable[, 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',))的方式传入多个参数 。 |
CopyRight 2018-2019 实验室设备网 版权所有 |