前言

最近在解决一些算法优化的问题,为了实时性要求,必须精益求精的将资源利用率用到极致。同时对算法中一些处理进行多线程或者多进程处理。

在对代码的调试过程中,发现在进程间队列使用耗时很长,特别是图片这种比较大的数据的时候。

可以先看一下我下面的demo是不是符合你的场景。

下面还有我的解决方案。

使用进程间Queue效率问题场景

代码样例如下,模拟从两个视频读取图片帧进行处理。

#!/user/bin/env python
# coding=utf-8
"""
@project : csdn-pro
@author  : 剑客阿良_ALiang
@file   : test13.py
@ide    : PyCharm
@time   : 2022-09-13 10:47:35
"""
import time
 
import cv2
from multiprocessing import Queue, Process
 
 
def fun1(q: Queue):
    cap = cv2.VideoCapture("11.mp4")
    a = []
    while cap.isOpened():
        ret, frame = cap.read()
        if ret:
            a.append(frame)
            if len(a) == 25:
                q.put(a)
                a = []
            time.sleep(0.038)
 
 
def fun2(q: Queue):
    cap = cv2.VideoCapture("3333333.mp4")
    a = []
    while cap.isOpened():
        ret, frame = cap.read()
        if ret:
            a.append(frame)
            if len(a) == 25:
                q.put(a)
                a = []
            time.sleep(0.038)
 
 
def fun3(q1: Queue, q2: Queue, q3: Queue):
    while True:
        st0 = time.time()
        a1 = q1.get()
        st1 = time.time()
        a2 = q2.get()
        st2 = time.time()
        print("{} 耗时:{} - {}".format(time.time(), st1 - st0, st2 - st1))
        q3.put((a1, a2))
 
 
def fun4(q3: Queue):
    while True:
        st0 = time.time()
        a1, a2 = q3.get()
        et = time.time()
        print("hhhh耗时: {}".format(et - st0))
 
 
if __name__ == '__main__':
    q1 = Queue()
    q2 = Queue()
    q3 = Queue()
    p1 = Process(target=fun1, args=(q1,))
    p2 = Process(target=fun2, args=(q2,))
    p3 = Process(target=fun3, args=(q1, q2, q3,))
    p4 = Process(target=fun4, args=(q3,))
    p1.start()
    p2.start()
    p3.start()
    p4.start()
    p1.join()
    p2.join()
    p3.join()
    p4.join()

代码说明:

1、上面模拟每秒25帧读取图片,并传递一个25帧的图片list给到队列。

我们看一下从queue获取图片list的效率。部分执行结果如下。

1663139091.3648114 耗时:1.6036181449890137 - 0.1361703872680664
hhhh耗时: 3.0635826587677
1663139093.056612 耗时:1.5302414894104004 - 0.1615591049194336
hhhh耗时: 1.6867034435272217
1663139094.7388775 耗时:1.5256507396697998 - 0.1566147804260254
hhhh耗时: 1.6849782466888428
1663139096.36547 耗时:1.4680161476135254 - 0.15857625007629395
hhhh耗时: 1.651228427886963
1663139097.9867501 耗时:1.4417593479156494 - 0.179520845413208
hhhh耗时: 1.609663963317871
1663139099.5894623 耗时:1.4391484260559082 - 0.16356372833251953
hhhh耗时: 1.7086796760559082
1663139101.3031366 耗时:1.5481102466583252 - 0.16556406021118164
hhhh耗时: 1.657604455947876
1663139102.9448056 耗时:1.470097303390503 - 0.1715717315673828
hhhh耗时: 1.5316739082336426
1663139104.5233243 耗时:1.4139580726623535 - 0.16456055641174316

Process finished with exit code -1

可以看出我们从进程队列get数据的耗时很长,从q3中同时获取的时间如蓝色标记,远大于1秒钟。

而整体获取图片帧的效率如红色标记,间隔时间大于1秒。

采用管道模式解决

这个时间间隔没法接受,我才用multiprocessing.Pipe管道来提前输入图片。

样例代码如下:

#!/user/bin/env python
# coding=utf-8
"""
@project : csdn-pro
@author  : 剑客阿良_ALiang
@file   : test13.py
@ide    : PyCharm
@time   : 2022-09-13 10:47:35
"""
import threading
import time
 
import cv2
from multiprocessing import Queue, Process, Pipe
 
 
def fun1(pipe_in):
    cap = cv2.VideoCapture("11.mp4")
    while cap.isOpened():
        ret, frame = cap.read()
        if ret:
            ret, frame = cap.read()
            pipe_in.send((int(time.time()), frame))
            time.sleep(0.038)
 
 
def fun2(pipe_in):
    cap = cv2.VideoCapture("3333333.mp4")
    while cap.isOpened():
        ret, frame = cap.read()
        if ret:
            ret, frame = cap.read()
            pipe_in.send((int(time.time()), frame))
            time.sleep(0.038)
 
 
def fun3(pipe_rev1, pipe_rev2):
    def handle(pipe_rev1, q1):
        _cul = 0
        a = []
        while True:
            _t, _frame = pipe_rev1.recv()
            if _cul == 0:
                a.append(_frame)
                _cul = _t
            elif _t > _cul != 0:
                if len(a) != 0:
                    q1.put(a)
                    _cul = _t
                    a = []
                    a.append(_frame)
            elif _t == _cul != 0:
                a.append(_frame)
 
    q1 = Queue()
    q2 = Queue()
    threading.Thread(target=handle, args=(pipe_rev1, q1,)).start()
    threading.Thread(target=handle, args=(pipe_rev2, q2,)).start()
    while True:
        if not q1.empty() and not q2.empty():
            st0 = time.time()
            _f1 = q1.get()
            st1 = time.time()
            _f2 = q2.get()
            et = time.time()
            print("{} 耗时:{} - {}".format(time.time(), st1 - st0, et - st1))
 
 
if __name__ == '__main__':
    pipe_in1, pipe_out1 = Pipe()
    pipe_in2, pipe_out2 = Pipe()
    p1 = Process(target=fun1, args=(pipe_in1,))
    p2 = Process(target=fun2, args=(pipe_in2,))
    p3 = Process(target=fun3, args=(pipe_out1, pipe_out2,))
    p1.start()
    p2.start()
    p3.start()
 
    p1.join()
    p2.join()
    p3.join()

代码说明:

1、通过两个线程不停从管道接受并写到内存的Queue里面,提前放到当前进程内存里。

看一下间隔是否稳定,部分执行结果如下

1663139886.0722673 耗时:0.003930091857910156 - 0.005983591079711914
1663139887.6837587 耗时:0.09677457809448242 - 0.09172177314758301
1663139888.472634 耗时:0.061833858489990234 - 0.05984067916870117
1663139889.5441313 耗时:0.07132482528686523 - 0.07080578804016113
1663139890.548978 耗时:0.06183457374572754 - 0.06881546974182129
1663139891.5112402 耗时:0.0637204647064209 - 0.0718080997467041
1663139892.4756596 耗时:0.06682205200195312 - 0.06978344917297363
1663139893.5788367 耗时:0.06779074668884277 - 0.07928323745727539

时间间隔还是比较稳定的。

总结

如果你遇到和我一样的场景,可以仔细观察一下进程间数据是否传输的比较慢。可以考虑和我一样的方式来解决。

到此这篇关于Python解决多进程间访问效率低的方法总结的文章就介绍到这了,更多相关Python多进程访问效率低内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Python解决多进程间访问效率低的方法总结的更多相关文章

  1. XCode 3.2 Ruby和Python模板

    在xcode3.2下,我的ObjectiveCPython/Ruby项目仍然可以打开更新和编译,但是你无法创建新项目.鉴于xcode3.2中缺少ruby和python的所有痕迹(即创建项目并添加新的ruby/python文件),是否有一种简单的方法可以再次安装模板?我发现了一些关于将它们复制到某个文件夹的信息,但我似乎无法让它工作,我怀疑文件夹的位置已经改变为3.2.解决方法3.2中的应用程序模板

  2. Swift基本使用-函数和闭包(三)

    声明函数和其他脚本语言有相似的地方,比较明显的地方是声明函数的关键字swift也出现了Python中的组元,可以通过一个组元返回多个值。传递可变参数,函数以数组的形式获取参数swift中函数可以嵌套,被嵌套的函数可以访问外部函数的变量。可以通过函数的潜逃来重构过长或者太复杂的函数。

  3. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  4. Swift、Go、Julia与R能否挑战 Python 的王者地位

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 红薯因 Swift 重写开源中国失败,貌似欲改用 Python

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  6. 你没看错:Swift可以直接调用Python函数库

    上周Perfect又推出了新一轮服务器端Swift增强函数库:Perfect-Python。对,你没看错,在服务器端Swift其实可以轻松从其他语种的函数库中直接拿来调用,不需要修改任何内容。以如下python脚本为例:Perfect-Python可以用下列方法封装并调用以上函数,您所需要注意的仅仅是其函数名称以及参数。

  7. Swift中的列表解析

    在Swift中完成这个的最简单的方法是什么?我在寻找类似的东西:从Swift2.x开始,有一些与你的Python样式列表解析相当的东西。(在这个意义上,它更像是Python的xrange。如果你想保持集合懒惰一路通过,只是这样说:与Python中的列表解析语法不同,Swift中的这些操作遵循与其他操作相同的语法。

  8. swift抛出终端的python错误

    每当我尝试启动与python相关的swift时,我都会收到错误.我该如何解决?

  9. 在Android上用Java嵌入Python

    解决方法看看this,它适用于J2SE,你可以尝试在Android上运行.

  10. android – getDrawable()的效率:是框架缓存的Drawable吗?

    或者这是否意味着每次都会从PNG文件中解码Drawable?在这种情况下,只调用getDrawable()两次并保持我自己对2Drawables的引用会更好.解决方法如果每次使用此方法时调用是否有效,则不响应您的问题.但正如@njzk2所说,你可以在你的切换按钮上使用StateSelector.我给你复制一个工作的例子.只需更改您的drawables的drawable名称即可.在您定义toogle按钮的xml上,将背景设置为:其中“toogle_selector”是我之前复制的文件的名称.有了这个,您可以

随机推荐

  1. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  2. python数学建模之三大模型与十大常用算法详情

    这篇文章主要介绍了python数学建模之三大模型与十大常用算法详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感想取得小伙伴可以参考一下

  3. Python爬取奶茶店数据分析哪家最好喝以及性价比

    这篇文章主要介绍了用Python告诉你奶茶哪家最好喝性价比最高,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  4. 使用pyinstaller打包.exe文件的详细教程

    PyInstaller是一个跨平台的Python应用打包工具,能够把 Python 脚本及其所在的 Python 解释器打包成可执行文件,下面这篇文章主要给大家介绍了关于使用pyinstaller打包.exe文件的相关资料,需要的朋友可以参考下

  5. 基于Python实现射击小游戏的制作

    这篇文章主要介绍了如何利用Python制作一个自己专属的第一人称射击小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试

  6. Python list append方法之给列表追加元素

    这篇文章主要介绍了Python list append方法如何给列表追加元素,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. Pytest+Request+Allure+Jenkins实现接口自动化

    这篇文章介绍了Pytest+Request+Allure+Jenkins实现接口自动化的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. 利用python实现简单的情感分析实例教程

    商品评论挖掘、电影推荐、股市预测……情感分析大有用武之地,下面这篇文章主要给大家介绍了关于利用python实现简单的情感分析的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

  9. 利用Python上传日志并监控告警的方法详解

    这篇文章将详细为大家介绍如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务,感兴趣的小伙伴可以了解一下

  10. Pycharm中运行程序在Python console中执行,不是直接Run问题

    这篇文章主要介绍了Pycharm中运行程序在Python console中执行,不是直接Run问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

返回
顶部