Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.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
为什么多处理中的get()在Python中花费了这么多时间?_Python_Multithreading_Face Recognition - Fatal编程技术网

为什么多处理中的get()在Python中花费了这么多时间?

为什么多处理中的get()在Python中花费了这么多时间?,python,multithreading,face-recognition,Python,Multithreading,Face Recognition,我正在尝试使用Python中的多重处理在树莓Pi上进行人脸识别。为了充分利用所有4个内核,我使用了多线程的概念。下面是我的(伪)代码的一部分: 据我所知,与实际图像捕获(三个周期)相比,显示图像会有一些延迟。我不明白的是,运行这个算法会有一定程度的卡住现象。可能是这样的: 平滑显示r1、r2、r3、r4的结果,然后卡住1s,然后平滑显示r1-r4和 或 平滑显示r2、r3、r4、r1的结果,然后卡住1s,然后平滑显示r2-r1和 它可以是从r1、r2、r3、r4开始的任何序列。我不明白是什么原因

我正在尝试使用Python中的多重处理在树莓Pi上进行人脸识别。为了充分利用所有4个内核,我使用了多线程的概念。下面是我的(伪)代码的一部分:

据我所知,与实际图像捕获(三个周期)相比,显示图像会有一些延迟。我不明白的是,运行这个算法会有一定程度的卡住现象。可能是这样的:

  • 平滑显示r1、r2、r3、r4的结果,然后卡住1s,然后平滑显示r1-r4和
  • 平滑显示r2、r3、r4、r1的结果,然后卡住1s,然后平滑显示r2-r1和
  • 它可以是从r1、r2、r3、r4开始的任何序列。我不明白是什么原因造成了这个卡住的东西?有人能帮忙分析吗?谢谢

    以下是分析的快照:


    下面是一个简单的示例,解释了您看到的模式

    假设你有4个人,面前有4杯空的水。把get()想象成“喝完你杯子里的水,我会等你喝完再继续”。把apply_async想象成“我要把你的杯子装满,开始喝酒,但我要继续”

    那么会发生什么:

    count == 1
    We fill person A's glass and they're drinking slowly
    We wait for person B to finish their cup, it's already empty, we move on
    
    count == 2
    We fill person B's glass and they're drinking slowly
    We wait for person C to finish their cup, it's already empty, we move on
    ...
    
    count == 4
    We fill person D's glass and they're drinking slowly
    We wait for person A to finish their cup
    
    好的,假设A需要30秒来完成他们的水,但是我们只需要5秒来完成上面的步骤


    我们现在要等25秒,等A喝完他们的酒,然后再继续。但是由于等待的时间很长,B、C和D三个人也喝完了酒,所以A喝完后,我们放大接下来的三个人,直到我们再次回到A。

    这里有一个简单的例子解释了你看到的模式

    假设你有4个人,面前有4杯空的水。把get()想象成“喝完你杯子里的水,我会等你喝完再继续”。把apply_async想象成“我要把你的杯子装满,开始喝酒,但我要继续”

    那么会发生什么:

    count == 1
    We fill person A's glass and they're drinking slowly
    We wait for person B to finish their cup, it's already empty, we move on
    
    count == 2
    We fill person B's glass and they're drinking slowly
    We wait for person C to finish their cup, it's already empty, we move on
    ...
    
    count == 4
    We fill person D's glass and they're drinking slowly
    We wait for person A to finish their cup
    
    好的,假设A需要30秒来完成他们的水,但是我们只需要5秒来完成上面的步骤


    我们现在要等25秒,等A喝完他们的酒,然后再继续。但是由于等待的时间很长,B、C和D三个人也喝完了酒,所以一旦A喝完,我们就放大接下来的三个人,直到我们再次回到A。

    如果你真的想尽快解雇这些工作,并在他们有空的情况下尽快获得结果,而不阻止解雇新的工作,你必须停止交错它们

    最简单的方法(假设您希望按照任务创建的顺序获得结果1)可能是在后台线程上等待,如下所示:

    q = queue.Queue()
    
    def handle():
        while True:
            res = q.get()
            output = res.get()
            showimage(output)
    
    threading.Thread(target=handle)
    
    while True:
        image = cap.read
        res = pool.apply_async(func, [image])
        q.put(res)
    
    这种精确的设计可能不起作用,例如,如果
    showimage
    必须在主线程上运行,则必须交换两个线程,如果
    cap.read
    也必须在主线程上运行,则需要管理多个队列,并使一切更加复杂,但这应该说明了这一点



    一,。如果您希望结果以任何顺序完成,那么从
    多处理.Pool
    切换到
    并发.futures.ProcessPoolExecutor
    可能会更简单,因为等待一组
    future
    比等待一组
    AsyncResult
    更容易。但是还有其他选择。

    如果你真的想尽快解雇这些工作,并在结果可用时立即获取结果,而不阻止解雇的新工作,你必须停止交错

    最简单的方法(假设您希望按照任务创建的顺序获得结果1)可能是在后台线程上等待,如下所示:

    q = queue.Queue()
    
    def handle():
        while True:
            res = q.get()
            output = res.get()
            showimage(output)
    
    threading.Thread(target=handle)
    
    while True:
        image = cap.read
        res = pool.apply_async(func, [image])
        q.put(res)
    
    这种精确的设计可能不起作用,例如,如果
    showimage
    必须在主线程上运行,则必须交换两个线程,如果
    cap.read
    也必须在主线程上运行,则需要管理多个队列,并使一切更加复杂,但这应该说明了这一点



    一,。如果您希望结果以任何顺序完成,那么从
    多处理.Pool
    切换到
    并发.futures.ProcessPoolExecutor
    可能会更简单,因为等待一组
    future
    比等待一组
    AsyncResult
    更容易。但是还有其他选择。

    如果处理器还没有完成图像处理,它会在get()调用中被阻塞吗?也许我不明白你的问题,我觉得这就是问题所在,但我不知道根本原因是什么。让我为您的分析提供一些分析结果的快照。哦,对了,我想我终于理解了您的问题描述。是的,get()调用会阻止您,但其他处理器仍在加载它们的值,因此每4次调用您都会被卡住。这可能需要一段时间才能完成。在启动每个任务
    n
    之后,您需要明确地等待任务
    n-3
    完成,然后再执行其他操作。如果您不想等待,而是想尽快启动任务,并在任务进入时处理它们,那么您需要更改它,以便在任务进入时等待,而不是与生成任务交织在一起。例如,您可以将每个
    AsyncResult
    粘贴到
    queue.queue
    上,并使用一个后台线程循环
    res=q.pop();输出=res.get();showimage(output)
    (或者,如果您不想让它们按顺序排列,您可以使用
    并发.futures.ProcessPoolExecutor中的
    future
    s,而不是
    多处理.Pool中的
    AsyncResult
    )如果处理器尚未完成图像处理,它将被卡在那里