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

2024-04-27 00:55:29 发布

您现在位置:Python中文网/ 问答频道 /正文

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

count = 1

while True:

    image = cap.read

    if count == 1:
        r1 = pool.apply_async(func, [image]) # this is the image process module
        output = r2.get()  # this is used to get the results from processor #2
        showimage(output)  # show the processed results
    elif count == 2:
        r2 = pool.apply_async(func, [image]) # this is the image process module
        output = r3.get()  # this is used to get the results from processor #3
        showimage(output)  # show the processed results
    elif count == 3:
        r3 = pool.apply_async(func, [image]) # this is the image process module
        output = r4.get()  # this is used to get the results from processor #4
        showimage(output)  # show the processed results
    elif count == 4:
        r4 = pool.apply_async(func, [image]) # this is the image process module
        output = r1.get()  # this is used to get the results from processor #1
        showimage(output)  # show the processed results
        count = 0
        count += 1

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

  1. 平滑显示r1、r2、r3、r4的结果,然后卡住1s,然后平滑显示r1-r4和。。。你知道吗

或者

  1. 平滑显示r2、r3、r4、r1的结果,然后卡住1s,然后平滑显示r2-r1和。。。你知道吗

它可以是从r1,r2,r3,r4开始的任何序列。我不明白是什么原因导致了这件事?有人能帮忙分析一下吗?谢谢。你知道吗

下面是分析的快照:

enter image description here


Tags: theimageoutputgetasynciscountthis
2条回答

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

最简单的方法是等待后台线程,如下所示:

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也必须在主线程上运行,则需要管理多个队列,并使一切更为复杂,但这应该说明了这一点。你知道吗


1。如果您想让结果以任何顺序结束,那么从multiprocessing.Pool切换到concurrent.futures.ProcessPoolExecutor可能会更简单,因为等待一组future比等待一组AsyncResult更容易。但还有其他选择。

下面是一个简单的例子来解释你看到的模式

假设你有4个人,面前有4杯空的水。把get()想象成“喝完你杯子里的水,我会等你喝完再继续”。把apply\u 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。你知道吗

相关问题 更多 >