如何在不阻塞while循环的前提下运行包含time.sleep()的函数
解决方法
当前代码出现阻塞的核心原因是同步调用逻辑:主线程执行到waiting()时会等待该函数完全执行完成(包括5秒的sleep等待),才会回到while循环继续执行摄像头读帧、画面渲染的逻辑,因此会出现循环停止的现象。
有两种常用的无阻塞实现方案:
方案1:多线程异步执行(改动最小)
直接将带sleep的等待逻辑放到独立子线程中运行,不会占用主线程的执行时间,while循环可以正常运行。
修改后的代码如下:
import cv2 import time import threading def waiting(): print("Inside function") # Running Some Tasks time.sleep(5) print("Done sleeping") def main(): cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() cv2.imshow("Webcam", frame) k = cv2.waitKey(10) if k == 32: # Press SPACEBAR for wait function # 创建并启动子线程运行waiting函数,不阻塞主线程 t = threading.Thread(target=waiting) t.start() elif k == 27: # Press ESC to stop code break cap.release() cv2.destroyAllWindows() if __name__ == "__main__": main()
注意:如果
waiting函数中需要操作OpenCV UI相关的资源(如修改渲染画面、弹出窗口等),不要直接在子线程中操作,否则可能出现程序崩溃,纯打印、文件IO、网络请求等逻辑不受影响。
方案2:时间戳判断实现非阻塞等待(无多线程开销)
如果不想引入多线程,可以直接去掉time.sleep,用时间戳差判断来实现等待逻辑,全程在主线程运行不会阻塞:
import cv2 import time def waiting_done(): print("Done sleeping") def main(): cap = cv2.VideoCapture(0) wait_trigger_time = None is_waiting = False while True: ret, frame = cap.read() cv2.imshow("Webcam", frame) k = cv2.waitKey(10) if k == 32 and not is_waiting: # 按空格触发等待,避免重复触发 print("Inside function") # 记录触发时间,标记等待状态 wait_trigger_time = time.time() is_waiting = True elif k == 27: break # 等待时间到了就执行后续逻辑 if is_waiting and time.time() - wait_trigger_time >= 5: waiting_done() is_waiting = False cap.release() cv2.destroyAllWindows() if __name__ == "__main__": main()
这种方案全程单线程运行,不需要考虑线程安全问题,适合等待逻辑比较简单的场景。
内容的提问来源于stack exchange,提问作者git-ruthvik
相关产品推荐
相关产品推荐

