如何在Python中同时运行多个函数?OpenCV场景问题答疑
解决OpenCV视频播放与asyncio协程并行运行的问题
问题根源
cv2.waitKey是阻塞函数:asyncio基于单线程事件循环运行,waitKey会完全占用线程,导致其他协程(比如function2)无法被调度执行。- 重复启动事件循环:代码中先后调用
loop.run_until_complete(main())和asyncio.run(main()),属于错误操作,会导致事件循环关闭后再次启动的异常。 function2无调度间隙:无限循环且无await操作会霸占事件循环,即使有其他任务也无法获得执行机会。
解决方案:用线程池隔离阻塞操作
将OpenCV的视频播放逻辑放到独立线程中执行,避免阻塞asyncio的事件循环,同时给function2添加调度间隙。
修改后的完整代码:
import cv2 import asyncio from concurrent.futures import ThreadPoolExecutor def play_video(): cap = cv2.VideoCapture('video.mp4') while True: ret, frame = cap.read() if ret: cv2.imshow('Frame', frame) # 阻塞操作在独立线程中执行,不影响asyncio事件循环 if cv2.waitKey(60) & 0xFF == ord('q'): break else: cap.release() cap = cv2.VideoCapture('video.mp4') ret, frame = cap.read() # 释放资源 cap.release() cv2.destroyAllWindows() async def function2(): while True: print("Inside Function 2") # 让出事件循环,让其他任务有执行机会 await asyncio.sleep(0.5) async def main(): # 创建线程池执行器,运行阻塞的视频播放任务 executor = ThreadPoolExecutor(max_workers=1) video_task = asyncio.get_event_loop().run_in_executor(executor, play_video) # 启动后台打印协程 task2 = asyncio.create_task(function2()) # 等待两个任务结束(视频播放退出或按q终止) await asyncio.gather(video_task, task2) if __name__ == "__main__": asyncio.run(main())
关键说明
- 线程池隔离:把OpenCV的阻塞操作放到独立线程,asyncio事件循环可以正常调度其他协程。
- 协程调度间隙:
function2中的await asyncio.sleep(0.5)让事件循环有机会切换任务,同时避免高频打印占用CPU。 - 资源清理:视频播放结束后主动释放摄像头资源并销毁窗口,避免内存泄漏。
内容的提问来源于stack exchange,提问作者user20431
相关产品推荐
相关产品推荐

