You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用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

火山引擎 最新活动