Python多线程能否提升含周期性人脸识别任务的程序执行速度?
结论
这种场景使用多线程/多进程完全可以解决运行doLongProcess()时的卡顿问题。你当前卡顿的核心原因是耗时的图像处理任务和主循环逻辑串行执行,doLongProcess()运行时会阻塞主循环的其他逻辑执行,把耗时任务放到后台独立的执行单元运行,就能避免阻塞主循环。
实现指导
前置注意事项
Python存在全局解释器锁(GIL),纯CPU密集的计算逻辑用多线程无法利用多核CPU提升运行速度,但你的doLongProcess()混合了IO操作(本地加载图像)和CPU计算(人脸检测、比对),哪怕仅用多线程把任务丢到后台执行,也能解决主循环卡顿的问题;如果要进一步提升图像处理的速度,建议搭配多进程实现。
具体实现步骤
- 用
queue.Queue做线程/进程间的通信载体,避免直接跨线程修改共享变量引发的线程安全问题:一个队列用于主循环向后台任务单元投递待处理的图像任务,另一个队列用于后台单元向主循环返回处理结果 - 主循环不再直接调用
doLongProcess(),只负责往任务队列丢待处理任务,同时轮询结果队列获取已经处理完成的结果 - 后台线程/进程独立从任务队列取任务执行
doLongProcess(),执行完成后把结果塞到结果队列即可
参考实现代码
import threading import queue # 初始化通信队列 task_queue = queue.Queue(maxsize=2) # 限制队列长度,避免旧任务堆积占内存 result_queue = queue.Queue() def long_process_worker(): while True: # 从队列取待处理任务,队列为空时会阻塞等待,不额外占用CPU img_path = task_queue.get() # 执行原有的图像处理逻辑 result = doLongProcess(img_path) # 结果塞回结果队列 result_queue.put(result) task_queue.task_done() # 启动后台守护线程,主程序退出时会自动销毁 worker_thread = threading.Thread(target=long_process_worker, daemon=True) worker_thread.start() # 原主循环逻辑 flag = 0 while True: if flag == 5: # 队列未满时才丢任务,避免阻塞主循环 if not task_queue.full(): task_queue.put("你的待处理图像路径") flag = 0 # 其他主循环逻辑 # 非阻塞轮询拿处理结果 if not result_queue.empty(): process_result = result_queue.get() # 后续处理返回的结果逻辑 flag += 1 exitCondition()
优化建议
- 可以根据你的设备性能调整任务队列的长度,以及图像处理的触发频率,避免任务堆积
- 人脸检测、比对属于CPU密集计算,如果处理速度达不到要求,可以把后台线程换成多进程实现,规避GIL的限制充分利用多核CPU
- 条件允许的话可以开启face_recognition的GPU加速支持,处理速度会有明显提升
内容的提问来源于stack exchange,提问作者Aayush Scet
相关产品推荐
相关产品推荐

