我在python中进行了一些视频分析,我想使用多线程来加速我的分析。 没有多线程,我的程序可以用以下方式编写
for frame in video:
res1 = run_costly_function1(frame, res_prev)
res2 = run_costly_function2(frame, res_prev)
res_prev = run_function2(res1, res2)
但是,函数run_costly_function1
和run_costly_function2
不相互依赖,因此可以并行运行。我也大量使用OpenCV函数,它释放了全局解释器锁,因此我认为多线程应该是可行的。
我可以想出两种不同的解决方法:
每次迭代启动一个新线程,其任务是计算run_costly_function2
:
for frame in video:
background_worker = Thread(target=run_costly_function2, args=(frame, res_rev))
background_worker.start()
res1 = run_costly_function1(frame, res_rev)
res2 = background_worker.join()
res_prev = run_function2(res1, res2)
拥有一个后台线程并使用队列与之通信:
q = queue.Queue()
background_worker = Thread(target=background_worker_func, args=(q,))
background_worker.start()
for frame in video:
q.put((frame, res_prev))
res1 = run_costly_function1(frame, res_prev)
res2 = q.get()
res_prev = run_function2(res1, res2)
我的问题是哪种方法更好?也许甚至有一个我忽略的第三种选择?如果它们有用,我愿意使用futures
之类的其他模块。
该解决方案应该扩展到每秒处理~100帧,我担心每秒创建100个线程(在方法1中)是昂贵的。但是,使用队列进行通信(在方法2中)实现起来似乎更复杂,因此更容易出错。
答案 0 :(得分:0)
使线程操作繁重,因此创建与您拥有的核心一样多的线程并且可以有效地利用它。我认为在你的情况下,不改变算法,最大线程数是3。
为降低转换成本,请勿将轻型操作移至单独的线程。 使用适合特定情况的最快同步素数。 Somtimes beter解决方案不是挂起线程并等待循环。
队列适用于处理一串独立数据,以防独立数据工作可以轻松地与多个工作人员分开。处理结果后可以传递给下一个队列,依此类推。