进程池
进程池下载图片(cpu+io混合型任务)
结果
总耗时: 18.28766179084778
示例代码
# -*- coding: utf-8 -*-
# 进程池 pool
import multiprocessing
import time
from io import BytesIO
import requests
from PIL import Image
def download_and_save(i):
print(f"开始下载img_{i}.jpg")
base_url = f"https://picsum.photos/seed/{i}/400/300"
try:
r = requests.get(base_url, timeout=5)
img = Image.open(BytesIO(r.content))
img = img.resize(size=(300, 300))
img.save(f"images/img_{i}.jpg")
return f"✅img_{i}.jpg下载成功"
except Exception as e:
print(e)
return f"❌img_{i}.jpg出错:{e}"
def main():
start_time = time.time()
with multiprocessing.Pool(processes=10) as pool:
result = pool.map(download_and_save, range(100))
for res in result:
print(res)
print(f"\n总耗时:", time.time() - start_time)
if __name__ == '__main__':
main()
Pool.map 总结
Pool.map() 是什么
- Pool.map(func,iterable) 普通的map,但在
多进程中并行执行
- 自动分发任务,自动回收结果,返回一个结果列表
- 默认会把参数列表,iterable拆分成各个子任务的参数
- 每个子进程处理一项,高效又稳定
Pool 常用模式对比
| 用法 |
说明 |
| pool.map(func, iterable) |
简单任务一把扔 |
| pool.apply(func, args) |
同步执行单个任务 |
| pool.apply_async(func, args) |
异步执行一个任务(可加回调) |
| pool.map_async(func, iterable) |
异步批处理(不阻塞) |
建议
- CPU密集型任务/大批量任务
- 自动创建进程、自动服用、清理
- 推荐map/map_async。
参考
https://zhuanlan.zhihu.com/p/1923372474415949643