当前位置: 首页 > article >正文

基于System V的共享内存函数使用指南


一、共享内存的核心价值

共享内存是进程间通信(IPC)中效率最高的方式,它通过直接读写物理内存实现数据共享,避免了内核与用户空间的多次数据拷贝。但因其无内置同步机制,需结合信号量互斥锁保证数据一致性


二、核心函数解析与使用示例

以下以System V共享内存函数为例,结合调试函数 ShmDebug 说明完整开发流程。

1. ​创建共享内存:shmget()
  • 功能:生成或获取共享内存标识符。
  • 参数
    • key:唯一标识符,建议用 ftok() 生成
    • size:内存大小(需按页对齐,通常为4KB的整数倍)
    • flag:权限标志(如 IPC_CREAT | 0666
  • 示例
    key_t key = ftok("/tmp/app.conf", 'A');  
    int shmid = shmget(key, 4096, IPC_CREAT | 0666);  
    if (shmid == -1) {  
        perror("shmget error");  
        exit(1);  
    }  
  • 注意ftok()的路径需稳定(如配置文件),避免因文件重建导致key变化
2. ​映射内存:shmat()
  • 功能:将共享内存附加到进程地址空间。
  • 参数
    • shmidshmget返回的标识符。
    • shmaddr:映射地址(通常设为NULL由系统分配)
  • 示例
    char *shm_addr = (char *)shmat(shmid, NULL, 0);  
    if (shm_addr == (char *)-1) {  
        perror("shmat error");  
        exit(1);  
    }  
3. ​数据读写

直接操作映射后的指针即可:

// 写入数据  
strcpy(shm_addr, "Hello from Process A!");  

// 读取数据  
printf("Received: %s\n", shm_addr);  
4. ​分离内存:shmdt()
  • 作用:解除进程与共享内存的映射关系(不删除内存段)
if (shmdt(shm_addr) == -1) {  
    perror("shmdt error");  
}  
5. ​控制与删除:shmctl()
  • 功能:删除共享内存或获取状态信息。
  • 示例(删除)​
    shmctl(shmid, IPC_RMID, NULL);  // 永久删除  

三、调试与状态监控(结合用户函数)

通过 shmctl + shmid_ds 结构体可获取共享内存的运行时状态,例如:

void ShmDebug(int shmid) {  
    struct shmid_ds shmds;  
    if (shmctl(shmid, IPC_STAT, &shmds) == -1) {  
        std::cerr << "shmctl error: " << strerror(errno) << std::endl;  
        return;  
    }  
    std::cout << "内存大小: " << shmds.shm_segsz << " 字节" << std::endl;  
    std::cout << "附加进程数: " << shmds.shm_nattch << std::endl;  
    std::cout << "创建时间: " << ctime(&shmds.shm_ctime);  
}  
  • 关键字段
    • shm_segsz:内存段大小
    • shm_nattch:当前附加的进程数,用于检测内存泄漏

四、实战案例:生产者-消费者模型

生产者代码(写入数据)​

// 创建共享内存  
key_t key = ftok(".", 'S');  
int shmid = shmget(key, 1024, IPC_CREAT | 0666);  
char *data = shmat(shmid, NULL, 0);  

sprintf(data, "Data: %d", rand() % 100);  // 写入随机数据  
shmdt(data);  

消费者代码(读取数据)​

int shmid = shmget(key, 1024, 0);  // 不创建,仅获取  
char *data = shmat(shmid, NULL, SHM_RDONLY);  // 只读模式  
printf("读取数据: %s\n", data);  
shmdt(data);  
shmctl(shmid, IPC_RMID, NULL);  // 删除共享内存  

五、注意事项与常见问题
  1. 同步机制:必须使用信号量(如sem_init)或文件锁(如flock)避免竞态条件
  2. 权限问题:确保进程对共享内存有读写权限(如0666
  3. 内存泄漏:监控shm_nattch,确保所有进程调用shmdt
  4. 跨平台限制:System V共享内存在不同Unix系统间行为可能不一致,建议优先用POSIX标准

六、扩展工具
  • ​**ipcs -m**:查看系统共享内存状态
  • ​**ipcrm -m <shmid>**:手动删除共享内存

http://www.kler.cn/a/589700.html

相关文章:

  • Flume详解——介绍、部署与使用
  • 2025深圳国际数字能源展全球招商启动,9月18日盛大开启
  • XGPT x DeepSeek:微步AI安全助手满血升级
  • 蓝桥杯备考-----》差分数组+二分答案 借教室
  • python局部变量和全局变量
  • nodejs 使用 puppeteer 打印PDF 有元素没有打印出来
  • 什么是广播系统语言传输指数 STIPA
  • 【云原生技术】容器技术的发展史
  • 市场监管总局升级12315平台 专项整治四大市场顽疾保障消费安全
  • Leetcode——151.反转字符串中的单词
  • 【Linux】Ext系列文件系统(上)
  • 机器人触觉的意义
  • 解决 openeuler 系统 docker 下载慢,docker 镜像加速
  • Unix时间戳BKP备份寄存器RTC实时时钟
  • docker配置国内镜像站链接
  • 【嵌入式】ESP_01S智能家居:可二次开发式智能灯控/门禁,勾勒智能生活新图景
  • 【算法】 进制转换(附蓝桥杯真题) python
  • Elasticsearch面试题
  • Docker命令解析:加速你的容器化之旅(以Nginx为例)
  • 爬虫逆向:逆向中用到汇编语言详细总结