我正在尝试在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
据我所知,与实际图像捕捉(三个周期)相比,显示图像会有一些延迟。我对运行算法的理解是,存在一定程度的卡住现象。它可能如下所示:
答案 0 :(得分:1)
这是一个简单的例子,解释了你所看到的模式
假设你有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完成,我们将放大接下来的3个人,直到我们再次回到A。
答案 1 :(得分:0)
如果您确实希望尽快启动作业,并在结果可用时立即获取结果,而不阻止新作业被触发,则必须停止交错。
执行此操作的最简单方法(假设您希望按任务创建的顺序 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
也必须运行你需要管理多个队列的主线程并使一切变得更复杂 - 但它应该表明这个想法。
<子> 1。如果您希望结果按照他们完成的任何顺序进行,那么从multiprocessing.Pool
切换到concurrent.futures.ProcessPoolExecutor
可能会更简单,因为等待future
组比在AsyncResult
组更容易一组spring-cloud-spring-service-connector
个。但还有其他选择。