Python multiprocessing进程池使用详解

Python multiprocessing进程池使用详解

先放官方文档

1. 进程池使用场景

当我们需要执行较大规模的并发任务时,如果每个分片任务都直接创建一个子进程并开始执行,程序很可能会瞬间创建很多子进程造成cpu资源拥挤,导致并行效率低。因此我们需要控制并发任务量,并且集中管理。

2. 常用函数详解

2.1 Pool

推荐方式:

from multiprocessing import Pool
p = Pool(size)
# 向pool下发任务
p.close()
p.join()

这样主进程会等待子进程全部执行完毕之后再退出。

踩坑注意:
with Pool(size) as p:这种方式with退出后子进程也会退出,无论子进程是否执行完。

官方解释

__enter__() returns the pool object, and __exit__() calls terminate()

即with进入的时候返回pool实例,退出时调用pool.terminate()

例:
在这里插入图片描述
在这里插入图片描述
子进程未完全执行就随主进程退出而退出了,数据未写入文件。

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

不推荐使用,向进程池添加单个任务,子进程会block主进程执行,相当于没有并行

返回值为func返回值

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

向进程池添加单个任务,非阻塞,使用场景:必须使用关键字参数,或者需要逐个任务添加(任务不同或者任务参数会发生变化等)等

返回数据类型为multiprocessing.pool.AsyncResult

func、callback、error_callback之间关系模型参考:

def apply_async(...):
	try:
		res = func(*args, **kwargs)
	except Exception as e:
		error_callback(e)  # 不需要函数返回值
	else:
		callback(res)  # 不需要函数返回值
	return res

使用样例:

p = Pool(10)
r = [p.apply_async(func, (i,), callback=cb, error_callback=ecb) for i in range(4)]
p.close()
p.join()
r = [res.get() for res in r]

2.4 starmap(func, iterable[, chunksize])

并行执行多个任务,阻塞主进程直至全部返回,可向func传多个位置参数,但不能传关键字参数
返回值为列表,列表中元素为func依次的返回值。

使用样例:

p = Pool(10)
r = p.startmap(func, [(1, 2, 3), (4, 5, 6)])
print(r)

2.5 startmap_async(func, iterable[, chunksize[, callback[, error_callback]]])

并行执行多个任务,不阻塞主进程,可向func传多个位置参数,但不能传关键字参数
返回值为List[AsyncResult]

2.6 map(func, iterable[, chunksize])

startmap简化版,限制func只能接受一个位置参数,不推荐使用。

2.7 map_async(func, iterable[, chunksize[, callback[, error_callback]]])

startmap_async简化版,限制func只能接受一个位置参数,不推荐使用。

2.8 close()

防止更多任务加入进程池,全部任务结束后所有进程退出。

2.9 terminate()

立即停止所有子进程即使进程任务未结束,当gc回收进程池时会立即调用。

2.10 join()

等待所有子进程退出,调用前必须先调用close()或者terminate()

2.11 AsyncResult

支持get([timeout]), wait([timeout]), ready(), successful()四个方法,get使用可参考上文样例,其他详见官方文档。

3. 常见问题

3.1 子进程未执行就退出

可能原因:

  • 使用了with,with退出自动结束子进程,详情参考上文2.1
  • 子进程无法获取到某些变量,因为子进程无法访问到主进程内存。常见一些无法pickle的数据结构,或是作用域外的变量
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kevin9436

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值