Python 多处理的良好示例实现?
我正在尝试将我的一个程序转换为使用多处理,最好是多处理池,因为这样做似乎更简单。在较高级别上,该过程是从图像创建一组补丁,然后将它们传递给GPU进行对象检测。CPU和GPU部分各需要4个,但是CPU有8个内核,它不必等待GPU,因为在数据通过GPU后不会对其进行进一步的操作 下面是一张我认为应该如何工作的图表: 为了帮助完成这一过程,我希望演示我的实现的高级版本。假设我们在一个包含10个图像的文件夹中循环浏览图像列表。我们一次调整4个图像的大小。然后我们一次将它们转换为黑白两种,我们可以将转换作为GPU过程的一部分。下面是代码的样子:Python 多处理的良好示例实现?,python,multithreading,python-2.7,multiprocessing,Python,Multithreading,Python 2.7,Multiprocessing,我正在尝试将我的一个程序转换为使用多处理,最好是多处理池,因为这样做似乎更简单。在较高级别上,该过程是从图像创建一组补丁,然后将它们传递给GPU进行对象检测。CPU和GPU部分各需要4个,但是CPU有8个内核,它不必等待GPU,因为在数据通过GPU后不会对其进行进一步的操作 下面是一张我认为应该如何工作的图表: 为了帮助完成这一过程,我希望演示我的实现的高级版本。假设我们在一个包含10个图像的文件夹中循环浏览图像列表。我们一次调整4个图像的大小。然后我们一次将它们转换为黑白两种,我们可以将转换
def im_resize(im, num1, num2):
return im.resize((num1, num2), Image.ANTIALIAS)
def convert_bw(im):
return im.convert('L')
def read_images(path):
imlist = []
for pathAndFileName in glob.iglob(os.path.join(path, "*")):
if pathAndFileName.endswith(tuple([".jpg", ".JPG"])):
imlist.append(Image.open(pathAndFileName))
return imlist
img_list = read_images("path/to/images/")
final_img_list = []
for image in img_list:
# Resize needs to run concurrently on 4 processes so that the next img_tmp is always ready to go for convert
img_tmp = im_resize(image, 100, 100)
# Convert is limited, need to run on 2 processes
img_tmp = convert_bw(img_tmp)
final_img_list.append(img_tmp)
特定进程数的原因是由于系统性能指标,这将减少运行时间。我只是想确保GPU不必等待CPU完成图像处理,我想让一个固定的队列充满预处理的图像,以便GPU运行。我希望在队列中保留大约4-10张预处理图像的最大大小。如果你们能帮我演示一下如何用这个简化的例子来实现这一点,我相信我能想出如何将它转化为我需要的东西
谢谢 下面是一个尝试,尝试实现您想要的:
...
# Mapping functions can only take one arg, we provide tuple
def img_resize_splat(a):
img_resize(*a)
if __name__=="__main__":
# Make a CPU pool and a GPU pool
cpu = Pool(4)
gpu = Pool(2)
# Hopefully this returns an iterable, and not a list with all images read into memory
img_list = read_images("path/to/images/")
# I'm assuming you want images to be processed as soon as ready, order doesn't matter
resized = cpu.imap_unordered(img_resize_splat, ((img, 100, 100) for img in img_list))
converted = gpu.imap_unordered(convert_bw, resized)
# This is an iterable with your results, slurp them up one at a time
for bw_img in converted:
# do something
有很多例子。你看过报纸了吗?它说明了几个场景。基本上,您希望在每个阶段都有一个单独的池,您希望在其中使用限制数量的工人进行工作。考虑一下您将对数据的输入集合应用什么函数转换以获得输出集合,然后使用
map
应用它,而不是使用Pool.map
。然后使用get
或join
尽可能晚地将数据封送回主进程。我已经看过了这些,但是由于python都是顺序的,我觉得它们没有充分说明进程是如何工作的,以及.join()如何精确地控制它们的执行。在我看来,加入完全停止了执行。对于一个需要将单个函数拆分为4个进程的简单进程来说,这些信息非常有用,但我的问题是,一个进程池需要在后台持续运行,而另一个进程池需要2个进程等待预处理的数据。我喜欢你的示例,但我有一些问题。图片列表可以小到1000张,但可以大到100000张,因此我想限制队列的大小。我希望运行4个并发进程来填充最大大小为10的队列,并在GPU每次从队列中移除图像时继续填充。顺序无关紧要,但队列似乎不是由cpu控制的..imap_unordered()?