如何使用Python读取由C语言创建的/dev/shm目录下的共享内存文件?
用Python读取/dev/shm中C创建的共享内存数据:可行且有具体方案
当然可以做到!/dev/shm下的这些文件其实是Linux系统把共享内存段映射成的虚拟文件,本质上和普通文件的读写逻辑类似,但因为数据是C程序按特定内存结构写入的,所以关键是要对应解析C端的数据结构体,下面是具体步骤和代码示例:
1. 先确认文件访问权限
首先确保你的Python进程有权限读取目标共享内存文件,执行命令查看权限:
ls -l /dev/shm/PGR_CTL_0x1E10_18474649
如果权限不足(比如只有root能读),可以用sudo运行Python脚本,或者联系管理员调整文件权限。
2. 必须拿到C端的数据结构体定义
这是最核心的一步:共享内存里存储的是C程序写入的二进制数据,只有知道对应的结构体,才能把二进制字节解析成有意义的数值。比如假设C程序里定义了这样的结构体:
// C端的结构体示例 typedef struct { int control_flag; // 4字节整数 unsigned long timestamp; // 8字节无符号长整型 float sensor_reading; // 4字节浮点数 } PGR_CTL_DATA;
你需要从开发C程序的团队拿到这个定义,或者通过逆向分析(比如用hexdump /dev/shm/PGR_CTL_0x1E10_18474649查看二进制内容推断结构)。
3. 用Python读取并解析数据
方法一:直接读取文件(简单易用)
用Python的struct模块解析二进制数据,对应C结构体的格式:
import struct # 格式字符串说明: # '<' 表示小端字节序(和大多数x86架构的C程序一致) # 'i' 对应int,'L'对应unsigned long,'f'对应float # 具体格式需要根据C端的实际结构体调整 STRUCT_FORMAT = '<iLf' try: # 以二进制只读模式打开共享内存文件 with open('/dev/shm/PGR_CTL_0x1E10_18474649', 'rb') as shm_file: # 读取对应结构体大小的字节数 raw_data = shm_file.read(struct.calcsize(STRUCT_FORMAT)) if not raw_data: print("共享内存文件为空,或读取失败") else: # 解析二进制数据为对应变量 control_flag, timestamp, sensor_reading = struct.unpack(STRUCT_FORMAT, raw_data) print(f"解析结果:") print(f"控制标志: {control_flag}") print(f"时间戳: {timestamp}") print(f"传感器读数: {sensor_reading:.2f}") except FileNotFoundError: print("目标共享内存文件不存在,请检查路径") except PermissionError: print("没有权限读取该文件,请尝试用sudo运行脚本")
方法二:用mmap映射内存(高效实时)
如果需要频繁读取共享内存(比如实时监控),用mmap模块直接把共享内存映射到Python进程的内存空间,效率更高:
import mmap import struct STRUCT_FORMAT = '<iLf' SHM_FILE_PATH = '/dev/shm/PGR_CTL_0x1E10_18474649' try: with open(SHM_FILE_PATH, 'rb') as shm_file: # 映射整个共享内存文件到进程内存,只读模式 with mmap.mmap(shm_file.fileno(), length=0, access=mmap.ACCESS_READ) as shm_mmap: # 读取并解析数据 raw_data = shm_mmap.read(struct.calcsize(STRUCT_FORMAT)) control_flag, timestamp, sensor_reading = struct.unpack(STRUCT_FORMAT, raw_data) print(f"实时解析结果:") print(f"控制标志: {control_flag}") print(f"时间戳: {timestamp}") print(f"传感器读数: {sensor_reading:.2f}") except FileNotFoundError: print("目标共享内存文件不存在,请检查路径") except PermissionError: print("没有权限读取该文件,请尝试用sudo运行脚本")
注意事项
- 字节序对齐:C程序的字节序(大端/小端)要和Python解析时的格式字符串一致(
<是小端,>是大端),如果解析结果完全不对,先检查字节序。 - 内存填充:C编译器会对结构体进行内存对齐(比如为了性能,可能在字段之间填充空字节),如果解析结果异常,需要确认结构体的实际内存布局(可以用C的
sizeof()计算结构体总大小,和Python的struct.calcsize()对比)。 - 动态数据:如果C程序会动态修改共享内存内容,你可以在循环中重复读取,实现实时监控。
内容的提问来源于stack exchange,提问作者Soaib




