为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Python Linux 中使用内存映射文件

如何在 Python Linux 中使用内存映射文件

翻过高山走不出你 2023-06-20 13:52:21
正如我在 Python 文档中看到的那样,Linux 中的 Python 可以完全支持内存映射文件。然而,当我试图将这个想法应用到我的应用程序中时。我无法运行示例。我的应用程序是将帧从 Python 文件(客户端)发送到另一个 Python 文件(服务器)。客户代码import mmapimport timeimport osimport cv2 as cvprint("Opening camera...")cap = cv.VideoCapture('/home/hunglv/Downloads/IMG_8442.MOV')mm = Nonetry:    while True:        ret, img = cap.read()        if not ret:            break        if mm is None:            mm = mmap.mmap(-1,img.size,mmap.MAP_SHARED, mmap.PROT_WRITE)        # write image        start = time.time()        buf = img.tobytes()        mm.seek(0)        mm.write(buf)        mm.flush()          stop = time.time()        print("Writing Duration:", (stop - start) * 1000, "ms")except KeyboardInterrupt:    passprint("Closing resources")cap.release()mm.close()服务器代码import mmapimport timeimport osimport cv2 as cvimport numpy as npshape = (1080, 1920, 3)n = np.prod(shape)mm = mmap.mmap(-1, n)while True:    # read image    print (mm)    start = time.perf_counter()    mm.seek(0)    buf = mm.read(12)    img = np.frombuffer(buf, dtype=np.uint8).reshape(shape)    stop = time.perf_counter()    print("Reading Duration:", (stop - start) * 1000, "ms")    cv.imshow("img", img)    key = cv.waitKey(1) & 0xFF    key = chr(key)    if key.lower() == "q":        breakcv.destroyAllWindows()mm.close()在服务器端,我将内存索引设置为 0,并尝试从内存中读取字节。但是,服务器似乎无法正确读取客户端的数据。[更新] 我试图在服务器端读出前 12 个字节。该值是恒定的,不再改变。b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'此外,随机帧的前 12 个字节是b'\xf5\xff\xff\xf0\xfa\xfe\xdf\xe9\xed\xd2\xdc\xe0'
查看完整描述

1 回答

?
翻阅古今

TA贡献1780条经验 获得超5个赞

首先,我找到了可能有效但它使用的示例tagName(客户端和服务器相同),这意味着它仅适用于 Window:

python-mmap-ipc


接下来我找到了适用于 Linux 的代码:

使用 mmap 在进程之间共享 Python 数据。

它在磁盘上创建真实文件,将其大小调整为图像大小,然后使用它的fdinmmap()


我使用网络摄像头进行测试。

服务器

import mmap

import time

import os

import cv2


print("Opening camera...")


cap = cv2.VideoCapture(0)

#print(cap.get(cv.CAP_PROP_FRAME_WIDTH))  # 640

#print(cap.get(cv.CAP_PROP_FRAME_HEIGHT)) # 480


shape = (480, 640, 3)

n = (480*640*3)


fd = os.open('/tmp/mmaptest', os.O_CREAT | os.O_TRUNC | os.O_RDWR)

#os.write(fd, b'\x00' * n)  # resize file

os.truncate(fd, n)  # resize file


mm = None

try:

    while True:

        ret, img = cap.read()

        

        if not ret:

            break

        

        if mm is None:

            mm = mmap.mmap(fd, n, mmap.MAP_SHARED, mmap.PROT_WRITE)  # it has to be only for writing


        # write image

        start = time.perf_counter()

        

        buf = img.tobytes()

        mm.seek(0)

        mm.write(buf)

        mm.flush()

        

        stop = time.perf_counter()


        print("Writing Duration:", (stop - start) * 1000, "ms")

except KeyboardInterrupt:

    pass


print("Closing resources")

cap.release()

mm.close()

客户


import mmap

import time

import os

import cv2

import numpy as np


shape = (480, 640, 3)

n = (480*640*3)


fd = os.open('/tmp/mmaptest', os.O_RDONLY)


mm = mmap.mmap(fd, n, mmap.MAP_SHARED, mmap.PROT_READ)  # it has to be only for reading


while True:

    # read image

    start = time.perf_counter()

    

    mm.seek(0)

    buf = mm.read(n)

    img = np.frombuffer(buf, dtype=np.uint8).reshape(shape)

    

    stop = time.perf_counter()


    print("Reading Duration:", (stop - start) * 1000, "ms")


    cv2.imshow("img", img)

    key = cv2.waitKey(1) & 0xFF

    key = chr(key)

    if key.lower() == "q":

        break

    

cv2.destroyAllWindows()

mm.close()

顺便说一句:可能mmap()与-1(不在磁盘上创建文件)可以与线程(或分叉)一起工作,因为它们共享相同的内存。


查看完整回答
反对 回复 2023-06-20
  • 1 回答
  • 0 关注
  • 172 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号