下面是关于“python 进程池pool使用详解”的完整攻略:
Python 进程池Pool使用详解
在处理大量的计算密集型任务时,我们通常都会使用多进程来提高程序执行效率。但是,每次手动管理进程的启动、停止可能会比较繁琐,而 Python 的进程池 Pool
则可轻松批量处理这些任务。
进程池Pool是什么
在 Python 中,multiprocessing.Pool
模块提供了一个进程池 Pool
的实现。
进程池 Pool
主要用于将大量需要通过多进程执行的任务分配给进程池中的多个进程进行执行。这样一来,我们就无需手动去创建和管理进程,而是交给进程池管理。
进程池的创建
进程池 Pool
的创建非常简单,只需要导入 multiprocessing
模块并调用 Pool
类即可。
import multiprocessing
# 创建进程池,进程数默认为系统CPU核心数量
pool = multiprocessing.Pool()
进程池中的任务
一旦创建了进程池 Pool
,我们就可以使用其提供的 apply()
、apply_async()
、map()
等方法来进行任务的提交和执行。
apply(func, args, kwds)
:执行一个用args
参数传递的可调用对象func
,并返回其结果。这个方法会阻塞进程池,直到执行完毕并返回。apply_async(func, args, kwds, callback=None)
:异步执行一个用args
参数传递的可调用对象func
,并返回一个AsyncResult
对象。该方法立即返回,不会等待任务的完成,但可以通过AsyncResult
对象获取到任务执行状态。map(func, iterable[, chunksize=None])
:对于可迭代对象iterable
中的每个元素,使用func
对其进行计算,返回一个结果列表。与apply()
方法类似,该方法也会阻塞进程池,直到任务全部执行完成并返回结果。
其中,callback
是一个可选的回调函数,用于对异步执行结果进行处理。
进程池的使用示例
示例1-计算1000000以内的质数
import multiprocessing
import time
def is_prime(num):
if num == 0 or num == 1:
return False
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
return False
return True
def calc_primes(start, end):
t = time.time()
print(f"进程{multiprocessing.current_process().name}计算中...")
result = []
for num in range(start, end):
if is_prime(num):
result.append(num)
print(f"进程{multiprocessing.current_process().name}计算完成,用时{time.time() - t:.2f}秒")
return result
if __name__ == "__main__":
# 创建进程池,5个进程
pool = multiprocessing.Pool(processes=5)
# 起始、结束数值
start, end = 0, 1000000
# 划分任务
step = (end - start) // 5
res = []
for i in range(5):
res.append(pool.apply_async(calc_primes, args=(start + i * step, start + (i + 1) * step)))
# 等待所有任务完成,获取结果
result = []
for r in res:
result.extend(r.get())
# 关闭进程池
pool.close()
pool.join()
# 输出结果
print(f"1000000以内的质数有{len(result)}个:\n{result[:10]}...")
在这个示例中,程序会启动一个含有5个进程的进程池 Pool
,然后将1000000以内的质数计算任务分成了5个部分,由进程池中的5个进程共同处理这5个部分任务。
运行结果如下:
进程ForkPoolWorker-1计算中...
进程ForkPoolWorker-2计算中...
进程ForkPoolWorker-3计算中...
进程ForkPoolWorker-5计算中...
进程ForkPoolWorker-4计算中...
进程ForkPoolWorker-1计算完成,用时10.84秒
进程ForkPoolWorker-2计算完成,用时10.92秒
进程ForkPoolWorker-3计算完成,用时11.00秒
进程ForkPoolWorker-5计算完成,用时11.04秒
进程ForkPoolWorker-4计算完成,用时11.09秒
1000000以内的质数有78498个:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]...
从结果可以看出,我们的程序用了11秒左右的时间就计算出了1000000以内的质数,并且在计算过程中,每个进程计算的部分都被输出了出来。
示例2-批量下载图片并统计总用时
import multiprocessing
import requests
import os
import time
def download_pic(url, save_path):
try:
# 文件已经存在则不再下载
if os.path.exists(save_path):
return 0
resp = requests.get(url, timeout=5)
with open(save_path, 'wb') as f:
f.write(resp.content)
return len(resp.content)
except:
return 0
if __name__ == "__main__":
# 创建进程池,5个进程
pool = multiprocessing.Pool(processes=5)
# 图片的url,本地存储路径
urls = ['http://img.ivsky.com/img/tupian/pic/201705/23/haian_wancheng-010.jpg',
'http://img.ivsky.com/img/tupian/pic/202003/30/xinan-004.jpg',
'http://img.ivsky.com/img/tupian/pic/202003/24/ertong_019.jpg',
'http://img.ivsky.com/img/tupian/pic/201705/24/senlin_wu-001.jpg',
'http://img.ivsky.com/img/tupian/pic/201904/07/changjing-001.jpg',
'http://img.ivsky.com/img/tupian/pic/201904/08/changjing-002.jpg',
'http://img.ivsky.com/img/tupian/pic/202001/09/gaoqingqixiang-015.jpg',
'http://img.ivsky.com/img/tupian/pic/202005/31/xueshan_shanja-030.jpg',
'http://img.ivsky.com/img/tupian/pic/202012/08/top_001.jpg',
'http://img.ivsky.com/img/tupian/pic/202005/24/xueshan_shanja-022.jpg',
]
save_paths = [f'./pics/pic{i}.jpg' for i in range(len(urls))]
# 下载任务
t1 = time.time()
res = []
for i in range(len(urls)):
res.append(pool.apply_async(download_pic, args=(urls[i], save_paths[i])))
# 等待所有任务完成,并计算总用时
total_size = 0
for r in res:
total_size += r.get()
total_time = time.time() - t1
# 关闭进程池
pool.close()
pool.join()
# 输出结果
print(f"下载完成!共下载了{len(urls)}张图片,总大小为{total_size/1024/1024:.2f}MB,总用时{total_time:.2f}秒...")
print("图片已保存在./pics目录下")
在这个示例中,程序会启动一个含有5个进程的进程池 Pool
,然后通过循环提交了10个需要下载的任务。由5个进程共同处理这10个任务,这些任务会尽量同时执行以减少总用时。
运行结果如下:
下载完成!共下载了10张图片,总大小为3.35MB,总用时1.16秒...
图片已保存在./pics目录下
从结果可以看出,我们的程序用了1.16秒左右的时间就把10个图片下载完成,并且总下载量是3.35MB左右。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python 进程池pool使用详解 - Python技术站