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

Linux 共享内存

Linux 共享内存

Linux 共享内存(Shared Memory)笔记

一、共享内存基础概念

  • 核心作用:多进程间高效共享数据的方式,进程无需血缘关系,可访问同一块内存空间。
  • 与全局变量的区别:多线程可直接共享进程地址空间,使用全局变量即可;但多进程地址空间相互独立,无法直接用全局变量共享数据,只能通过共享内存实现
  • 工作原理:进程将共享内存连接到自身地址空间中,修改共享内存数据后,其他进程读取的数据也会同步改变。
  • 关键特性:无内置锁机制,多进程同时读写时需用信号量等方式同步。

二、共享内存操作核心函数

1. shmget:创建/获取共享内存

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
  • 参数说明
    • key:共享内存的键值(唯一标识,常用十六进制如 0x5005)。
    • size:共享内存大小(字节为单位)。
    • shmflg:访问权限+创建标志,如 0640 | IPC_CREAT(创建+读写权限)。
  • 返回值:成功返回共享内存ID(shmid),失败返回 -1

2. shmat:连接共享内存到进程地址空间

void *shmat(int shmid, const void *shmaddr, int shmflg);
  • 参数说明
    • shmidshmget 返回的共享内存ID。
    • shmaddr:指定连接地址,填 0 表示由系统自动分配。
    • shmflg:标志位,填 0 表示读写模式。
  • 返回值:成功返回共享内存起始地址,失败返回 (void *)-1

3. shmdt:分离共享内存

int shmdt(const void *shmaddr);
  • 作用:将共享内存从当前进程地址空间分离,不会删除共享内存本身。
  • 参数shmat 返回的共享内存地址。
  • 返回值:成功返回 0,失败返回 -1

4. shmctl:操作共享内存(常用删除)

int shmctl(int shmid, int command, struct shmid_ds *buf);
  • 参数说明
    • shmid:共享内存ID。
    • command:操作指令,常用 IPC_RMID(删除共享内存)。
    • buf:控制信息结构地址,删除时填 0 即可。
  • 返回值:成功返回 0,失败返回 -1

三、共享内存操作命令

# 查看系统所有共享内存
ipcs -m# 删除指定共享内存(shmid为共享内存ID)
ipcrm -m <shmid>

四、完整示例代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
using namespace std;//只能用c++自带的,不能用stl
// 定义共享内存中存储的数据结构
struct stgirl {int no;         // 编号char name[51];  // 姓名(注意:共享内存中不能使用string)
};int main(int argc, char *argv[]) {if (argc != 3) {cout << "Usage: ./shmget <no> <name>\n";return -1;}// 第一步:创建/获取共享内存int shmid = shmget(0x5005, sizeof(stgirl), 0640 | IPC_CREAT);if (shmid == -1) {cout << "shmget(0x5005) failed.\n";return -1;}cout << "shmid = " << shmid << endl;// 第二步:将共享内存连接到当前进程地址空间stgirl *ptr = (stgirl *)shmat(shmid, 0, 0);if (ptr == (void *)-1) {cout << "shmat() failed\n";return -1;}// 第三步:读写共享内存数据cout << "原值: no = " << ptr->no << ", name = " << ptr->name << endl;ptr->no = atoi(argv[1]);        // 修改编号strcpy(ptr->name, argv[2]);     // 修改姓名cout << "新值: no = " << ptr->no << ", name = " << ptr->name << endl;// 第四步:分离共享内存shmdt(ptr);// 第五步:删除共享内存(可选,根据需求决定是否保留)if (shmctl(shmid, IPC_RMID, 0) == -1) {cout << "shmctl failed\n";return -1;}return 0;
}

五、代码运行与测试

# 编译
g++ -o shmget shmget.cpp# 运行(写入数据)
./shmget 1001 "Alice"# 查看共享内存(运行前后对比)
ipcs -m# 再次运行(读取/修改数据)
./shmget 1002 "Bob"

六、注意事项

  1. 数据类型限制:共享内存中不能使用 string 等非POD类型,建议用数组或结构体存储数据。
  2. 同步问题:共享内存无锁,多进程读写时需用信号量、互斥锁等同步。
  3. 权限问题:root创建的共享内存,普通用户无法删除,需注意权限设置。
  4. 内存泄漏:进程退出前必须调用 shmdt 分离共享内存,否则会导致共享内存无法释放。
http://www.jsqmd.com/news/775872/

相关文章:

  • GEO优化公司的性价比哪家高?开眼营销优势多 - myqiye
  • 从五角星到雷达图:用CocosCreator Graphics组件封装一个可复用的自定义图表库
  • 不只是运行:用GDB深入调试NEMU模拟器内核与BenOS固件(附GDB 10.2升级指南)
  • ComfyUI-Manager离线模式深度解析:无网络环境下的高效管理实战指南
  • 2026年GEO如何选购 - 工业推荐榜
  • 关于cppm?采购从业者必看的权威全解析(含报考指南) - 中供国培
  • 抖音内容高效下载终极指南:从零开始掌握批量无水印保存技巧
  • ChatGPT 学英语实战:口语陪练、写作润色与语法纠偏的正确姿势
  • 2026年西安画册印刷厂、活页环装定制与快印服务深度横评|松林森彩印官方联系指南 - 精选优质企业推荐官
  • 企业重点人群享受税收优惠如何申请? - myqiye
  • 你的定时任务踩过调休的坑吗?用chinese_calendar为Python脚本加上‘中国节假日感知’
  • Java 21 开发技术主题:模式匹配的最佳实践
  • RAG 系列(九):效果不好怎么定位——用 RAGAS 做根因诊断
  • spring-ai-alibaba-agent 260508
  • mapset
  • 【OC】自定义Cell
  • 武汉明德智学高中课后辅导口碑如何 - myqiye
  • DeepSeek免费API逆向工程:技术原理、部署与实战应用
  • BabelDOC:专业PDF智能翻译工具的5分钟终极指南
  • 动态化漏洞利用框架:自动化适配与运行时决策机制解析
  • 类似龙虾企业级OpenClaw安全替代方案推荐:支持私有化部署的智能体平台 - 品牌2026
  • ThinkPad风扇控制终极指南:用TPFanCtrl2实现智能散热与静音平衡
  • 5倍效率跃迁:智能投递系统的数据驱动求职革命
  • 2026年新疆游骏文旅旅游人才吸引力排名 - myqiye
  • 猫抓终极指南:构建专业级浏览器资源嗅探与流媒体处理系统
  • Java 21 开发技术:简化数据流处理的模式匹配新探索
  • B站视频转文字:用bili2text轻松搞定内容提取难题
  • 3分钟解锁网易云音乐NCM加密文件:Windows图形化工具终极指南
  • 2026年南京办公设备厂家口碑推荐榜:南京打印机、南京复印机、南京印刷机、南京扫描仪、办公设备厂家选择指南 - 海棠依旧大
  • 2026年口碑好的龙井茶场有哪些? - mypinpai