Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 多处理的良好示例实现?_Python_Multithreading_Python 2.7_Multiprocessing - Fatal编程技术网

Python 多处理的良好示例实现?

Python 多处理的良好示例实现?,python,multithreading,python-2.7,multiprocessing,Python,Multithreading,Python 2.7,Multiprocessing,我正在尝试将我的一个程序转换为使用多处理,最好是多处理池,因为这样做似乎更简单。在较高级别上,该过程是从图像创建一组补丁,然后将它们传递给GPU进行对象检测。CPU和GPU部分各需要4个,但是CPU有8个内核,它不必等待GPU,因为在数据通过GPU后不会对其进行进一步的操作 下面是一张我认为应该如何工作的图表: 为了帮助完成这一过程,我希望演示我的实现的高级版本。假设我们在一个包含10个图像的文件夹中循环浏览图像列表。我们一次调整4个图像的大小。然后我们一次将它们转换为黑白两种,我们可以将转换

我正在尝试将我的一个程序转换为使用多处理,最好是多处理池,因为这样做似乎更简单。在较高级别上,该过程是从图像创建一组补丁,然后将它们传递给GPU进行对象检测。CPU和GPU部分各需要4个,但是CPU有8个内核,它不必等待GPU,因为在数据通过GPU后不会对其进行进一步的操作

下面是一张我认为应该如何工作的图表:

为了帮助完成这一过程,我希望演示我的实现的高级版本。假设我们在一个包含10个图像的文件夹中循环浏览图像列表。我们一次调整4个图像的大小。然后我们一次将它们转换为黑白两种,我们可以将转换作为GPU过程的一部分。下面是代码的样子:

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()?