简介
共享内存
mmap
- 官网文档:https://docs.python.org/2/library/mmap.html
使用方法
创建:创建并返回一个 mmap 对象
m = mmap.mmap(fileno, length[, flags[, prot[, access[, offset]]]])
- fileno: 文件描述符,可以是file对象的fileno()方法,或者来自os.open(),在调用mmap()之前打开文件,不再需要文件时要关闭。
os.O_RDONLY 以只读的方式打开 Read only
os.O_WRONLY 以只写的方式打开 Write only
os.O_RDWR 以读写的方式打开 Read and write
os.O_APPEND 以追加的方式打开
os.O_CREAT 创建并打开一个新文件
os.O_EXCL os.O_CREAT| os.O_EXCL 如果指定的文件存在,返回错误
os.O_TRUNC 打开一个文件并截断它的长度为零(必须有写权限)
os.O_BINARY 以二进制模式打开文件(不转换)
os.O_NOINHERIT 阻止创建一个共享的文件描述符
os.O_SHORT_LIVED
os.O_TEMPORARY 与O_CREAT一起创建临时文件
os.O_RANDOM 缓存优化,但不限制从磁盘中随机存取
os.O_SEQUENTIAL 缓存优化,但不限制从磁盘中序列存取
os.O_TEXT 以文本的模式打开文件(转换)
-
**length:**要映射文件部分的大小(以字节为单位),这个值为0,则映射整个文件,如果大小大于文件当前大小,则扩展这个文件。
-
flags:MAP_PRIVATE:这段内存映射只有本进程可用;mmap.MAP_SHARED:将内存映射和其他进程共享,所有映射了同一文件的进程,都能够看到其中一个所做的更改;
-
**prot:**mmap.PROT_READ, mmap.PROT_WRITE 和 mmap.PROT_WRITE | mmap.PROT_READ。最后一者的含义是同时可读可写。
-
**access:**在mmap中有可选参数access的值有:
ACCESS_READ:读访问。
ACCESS_WRITE:写访问,默认。
ACCESS_COPY:拷贝访问,不会把更改写入到文件,使用flush把更改写到文件。
对象方法
- m.close()
- m.find(str, start=0)
- m.flush([offset, n])
- m.move(dstoff, srcoff, n)
- m.read(n)
- m.read_byte()
- m.readline()
- m.resize(n)
- m.seek(pos, how=0)
- m.size()
- m.tell()
- m.write(str)
- m.write_byte(byte)
使用示例
写入数据进共享内存
import ctypes
import mmap # 核心库
import os
import struct
import numpy as np
# 创建内存映射文件句柄
fd = os.open('tmp/mmaptest', os.O_CREAT | os.O_TRUNC | os.O_RDWR)
# 建立内存缓冲区
# not win32
buf = mmap.mmap(fd, mmap.PAGESIZE, mmap.MAP_SHARED, mmap.PROT_WRITE)
# win32
buf = mmap.mmap(fd, 67108864, access = mmap.ACCESS_WRITE)
# 向buf中写入文件(二进制格式)
f = open('tmp/test2.bmp', 'rb').read()
buf.write(b'abc') # 写入字符串
buf.write(f) # 写入文件
# 当前指针位置
buf.tell()
# 移动指针到第11个字节
buf.seek(10)
# 将内存中的信息写入文件
buf.flush(0, 100)
# 关闭
buf.close()
从共享内存中读取数据
import mmap
import os
import struct
import cv2
import numpy as nps
# 创建内存映射文件句柄
fd = os.open('share_memory/tmp/mmaptest', os.O_RDONLY)
# 建立内存缓冲区
# not win32
buf = mmap.mmap(fd, mmap.PAGESIZE, mmap.MAP_SHARED, mmap.PROT_READ)
# win32
buf = mmap.mmap(fd, 67108864, access = mmap.ACCESS_READ)
# 读取并打印缓冲区中指定区域内存
string_length = 136
string, = struct.unpack('{}s'.format(string_length), buf[:string_length])
print(string)
# 将部分区域转换为需要的格式并使用(图像)
np_str = np.fromstring(buf[:string_length], dtype='uint8')
img = cv2.imdecode(np_str, flags=-1)
# 纯图像像素数据(仅需转换字符串为uint8)即可
data = np.fromstring(buf[:string_length], dtype='uint8')
img = data.reshape([10,10])
参考资料
- https://docs.python.org/2/library/mmap.html
- https://zhuanlan.zhihu.com/p/166330573
- https://www.cnblogs.com/zhoujinyi/p/6062907.html