Python threading中self.running标识控制双目相机线程启停异常问题
问题根因
Python标准库的Thread实例仅允许调用一次start()方法,一旦run()方法执行完成,线程就会永久终止,仅修改self.running标志无法重新唤醒已经退出的线程。你遇到的两个现象具体原因如下:
- 初始
self.running = True:首次启动线程后run()方法正常执行采集逻辑,按下停止键将self.running设为False后,while循环退出、run()方法执行完毕,线程终止。后续按下启动键仅修改了标志位,没有重新启动新的线程,因此没有反应。 - 初始
self.running = None:while判断逻辑中None等价于假,若你没有修改run()中的循环条件,线程启动后会直接退出;如果你自行修改了循环条件为while self.running is not None,则将self.running设为False不会触发循环退出,因此无法终止线程。
修复方案
推荐采用「线程常驻+标志位控制采集状态」的方案,避免反复创建销毁线程、开关相机设备带来的性能开销,修改逻辑如下:
- 将
run()方法拆分为两层循环:外层维持线程存活,内层仅在采集标志为真时执行读帧、渲染逻辑 - 停止采集时仅退出内层循环,不终止外层循环
- 新增资源释放逻辑,程序退出时主动释放相机、销毁OpenCV窗口
可运行修改后代码
from threading import Thread import time import cv2 import keyboard class LeftFrame(Thread): def __init__(self): super().__init__() self.daemon = True # 设为守护线程,主程序退出时自动销毁 self.running = False # 采集控制标志 self.thread_alive = True # 线程存活控制标志 def run(self): cap = cv2.VideoCapture(0) # 外层循环维持线程存活 while self.thread_alive: # 内层循环仅在running为True时执行采集 while self.running: success, img = cap.read() if not success: break cv2.imshow("left_cam", img) cv2.waitKey(1) # 停止采集时短暂休眠降低CPU占用 time.sleep(0.01) # 线程退出前释放相机 cap.release() cv2.destroyWindow("left_cam") def stop_capture(self): self.running = False def start_capture(self): self.running = True def terminate_thread(self): self.running = False self.thread_alive = False # 初始化并启动常驻线程 left_cam_thread = LeftFrame() left_cam_thread.start() if __name__ == "__main__": while True: # 按f停止采集 if keyboard.is_pressed('f'): left_cam_thread.stop_capture() time.sleep(1) # 按s启动采集 if keyboard.is_pressed('s'): left_cam_thread.start_capture() time.sleep(1) # 按q退出整个程序 if keyboard.is_pressed('q'): left_cam_thread.terminate_thread() left_cam_thread.join() cv2.destroyAllWindows() break
双目适配提示
右相机线程可以复用上述类逻辑,仅修改相机ID和窗口名称即可,两个线程相互独立不会互相干扰。
内容的提问来源于stack exchange,提问作者Mr Z
相关产品推荐
相关产品推荐

