尝试更好地理解多处理以及如何将其用于以下场景。
我有一个包含100,000张图片的文件夹。我有一个python脚本,它接收每个图像,对图像执行一些操作并将结果存储到另一个目录中。
图像上的每个操作都需要5秒钟。
我的问题如下 -
当我的脚本在单个图像上执行时。如果我使用top命令查看cpu statistics,我可以看到我的cpu或内存都不是100%(这是一个多核处理器)
此外,我可以通过简单地在不同的shell中启动许多python脚本来每分钟处理更多图像。
以更快的方式执行此任务的pythonic方法是什么?如果图像数量增加,我如何水平缩放?
任何资源/评论都会有所帮助。
答案 0 :(得分:0)
您可以使用asyncio
库同时处理图像。您只需定义一个事件循环,将任务注册到事件循环中,这就是全部。系统决定下一个运行哪个。当一个任务被I / O绑定(在你的情况下,将值存储到系统中的某个地方),或等待来自某个地方的响应时,系统从事件循环中选择另一个任务而不是等待,依此类推。
答案 1 :(得分:0)
打开/读/写文件的I / O操作是导致cpu空闲的操作
处理图像时,它通常是一个矩阵乘法并占用大量的cpu资源,可以根据cpu内核并行完成(给出或取2 *个内核)
我的建议是根据任务使用不同的线程池,为了处理文件,你可以创建任意数量的线程,而不需要太多的性能降级,但是处理图像,即使用字节数组进行计算可以扩展到与cpu核心,你应该注意到性能降级
我建议使用worker-queue模式描述here
您还可以查看事件循环实现,由于其非阻塞性质可能会产生更好的结果,您可以找到示例here
请记住,要充分利用cpu核心,你应该创建多个事件循环线程,每个核心一个(或两个),线程在cpu核心上自动缩放(大多数os)
答案 2 :(得分:0)
您可以使用binge
(pip install binge
) - 它是一个通用的多处理包装器:
def image_worker(image_path, output_path):
(load image, process, and save)
return None
img_paths = ['./img1.png',
'./img2.png',
...
'./img100000.png']
from binge import B
result = B(worker, cores=4)(img_paths, '../otherfolder/')
其中cores
是将使用多少进程。结果将是image_worker的返回值列表,即Nones列表。