Python多进程multiprocess之多进程返回值获取

由于python内部GIL(全局解释器锁)的存在,所以python的线程实际上并不能很好的起到任务并行处理的作用,尤其是无法充分利用系统多核的优势,因此想要利用多核处理并行任务,就需要用到多进程——multiprocess。由于多进程任务时,经常需要返回函数的结果,这里主要关注进程返回值的获取。
首先定义一个简单函数:

def add(n):
	s = 0
	for i in range(n):
		s += 1
	print(f'子进程{n}')
	return s

用串行的方法:

import time
lists = [10000000, 20000000, 5000000, 30000000]
results = []
start = time.time()
for n in lists:
	results.append(add(n))
print(f'recurrent time cost: {time.time() - start}s')

打印结果:

子进程10000000
子进程20000000
子进程5000000
子进程30000000
recurrent time cost: 3.95 s

很明显,是按顺序执行函数的。下面用多进程实现,看速度是否会提升。

from multiprocessing import Pool
pool = Pool(processes=4) # 子进程数
results = []
start = time.time()
for n in lists:
	result = pool.apply_async(add, (n,) 
	# apply_async是apply的并行变体,使用apply会造成队列阻塞,没法实现并行。
	# 输入是函数名称(注意没有括号),以及函数的参数(以元组形式按位置排列输入)
	results.append(result)
	# 把返回的结果添加到results中
pool.close() # 关闭进程池,不能再添加进程
pool.join() # 主进程等待所有进程执行完毕
print(f'multi-process time cost: {time.time() - start}s')

#获取结果
for res in results:
	print(res.get())

执行的结果:

子进程5000000
子进程10000000
子进程20000000
子进程30000000
multi-process time cost: 1.91 s
10000000
20000000
5000000
30000000

可以看到快的先执行完,慢的后执行完,但结果返回的顺序仍与进程添加的顺序一致。

0813更新—使用线程池测试

上面的例子表明python的多进程确实可以实现多任务并行,下面测试多线程的效果,是否无法实现CPU密集型的多任务并行。同样我们使用上面的add函数作为基础运算函数。代码如下:

# 使用线程池
from concurrent.futures import ThreadPoolExecutor
pool = ThreadPoolExecutor(max_workers=4)
start = time.time()
for res in pool.map(add, lists):
	# print(res)
	pass
print(f'multi-tfreads time cost: {time.time() - start}s')

看一下结果

子进程5000000
子进程10000000
子进程20000000
子进程30000000
multi-tfreads time cost: 5.01 s

可以看到耗时比for循环还长,因为存在线程开启销毁等时间消耗,所以python的线程对CPU密集型任务不太行,这种情况下还是用多进程执行并行任务的好!

你可能感兴趣的:(python,python,多线程)