You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中同时运行多个函数?OpenCV场景问题答疑

解决OpenCV视频播放与asyncio协程并行运行的问题

问题根源

  1. cv2.waitKey是阻塞函数:asyncio基于单线程事件循环运行,waitKey会完全占用线程,导致其他协程(比如function2)无法被调度执行。
  2. 重复启动事件循环:代码中先后调用loop.run_until_complete(main())和asyncio.run(main()),属于错误操作,会导致事件循环关闭后再次启动的异常。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 03:01:06