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

C++共享内存小白入门指南

什么是共享内存?

想象一下,你和你的室友共用一个冰箱。你们都可以往里面放东西,也可以从里面拿东西,这就是共享内存的基本概念!在C++中,共享内存是一种让不同进程(可以理解为不同的程序)能够访问同一块内存区域的技术。

为什么要使用共享内存?

  1. 高效通信:进程间通信最快的方式之一
  2. 数据共享:多个程序可以访问相同数据
  3. 减少复制:不需要在不同进程间复制大量数据

基础知识准备

在深入之前,你需要知道:

  • 进程:正在运行的程序实例
  • 内存:程序存储数据的地方
  • 系统调用:操作系统提供的功能接口

共享内存使用步骤(Linux/Unix系统)

第一步:创建共享内存

#include<sys/ipc.h>#include<sys/shm.h>#include<iostream>intmain(){// 生成一个唯一的keykey_t key=ftok("shmfile",65);// 创建共享内存段,1024字节大小// IPC_CREAT表示创建,0666是权限(可读可写)intshmid=shmget(key,1024,IPC_CREAT|0666);if(shmid<0){std::cerr<<"创建共享内存失败"<<std::endl;return1;}std::cout<<"共享内存创建成功,ID: "<<shmid<<std::endl;return0;}

第二步:附加到共享内存

#include<sys/ipc.h>#include<sys/shm.h>#include<iostream>#include<cstring>intmain(){key_t key=ftok("shmfile",65);intshmid=shmget(key,1024,0666);// 附加到共享内存char*shared_memory=(char*)shmat(shmid,nullptr,0);if(shared_memory==(char*)-1){std::cerr<<"附加到共享内存失败"<<std::endl;return1;}// 写入数据到共享内存std::strcpy(shared_memory,"你好,共享内存!");std::cout<<"数据已写入共享内存"<<std::endl;// 分离共享内存(但不删除)shmdt(shared_memory);return0;}

第三步:读取共享内存数据

#include<sys/ipc.h>#include<sys/shm.h>#include<iostream>intmain(){key_t key=ftok("shmfile",65);intshmid=shmget(key,1024,0666);// 附加到共享内存char*shared_memory=(char*)shmat(shmid,nullptr,0);std::cout<<"从共享内存读取: "<<shared_memory<<std::endl;// 分离共享内存shmdt(shared_memory);return0;}

第四步:删除共享内存

#include<sys/ipc.h>#include<sys/shm.h>#include<iostream>intmain(){key_t key=ftok("shmfile",65);intshmid=shmget(key,1024,0666);// 删除共享内存段shmctl(shmid,IPC_RMID,nullptr);std::cout<<"共享内存已删除"<<std::endl;return0;}

完整示例:进程间通信

写入进程(writer.cpp)

#include<sys/ipc.h>#include<sys/shm.h>#include<iostream>#include<cstring>#include<unistd.h>intmain(){// 生成keykey_t key=ftok("shmfile",65);// 创建共享内存(1KB大小)intshmid=shmget(key,1024,IPC_CREAT|0666);// 附加到共享内存char*str=(char*)shmat(shmid,nullptr,0);std::cout<<"写入进程启动,等待输入..."<<std::endl;// 连续写入数据for(inti=1;i<=5;i++){sprintf(str,"消息 %d",i);std::cout<<"写入: "<<str<<std::endl;sleep(2);// 等待2秒}// 写入结束标志strcpy(str,"结束");// 分离共享内存shmdt(str);return0;}

读取进程(reader.cpp)

#include<sys/ipc.h>#include<sys/shm.h>#include<iostream>#include<cstring>#include<unistd.h>intmain(){// 生成相同的keykey_t key=ftok("shmfile",65);// 获取共享内存intshmid=shmget(key,1024,0666);// 附加到共享内存char*str=(char*)shmat(shmid,nullptr,0);std::cout<<"读取进程启动,等待数据..."<<std::endl;// 持续读取数据while(true){std::cout<<"读取: "<<str<<std::endl;// 检查是否收到结束标志if(strcmp(str,"结束")==0){break;}sleep(1);// 每秒检查一次}// 分离共享内存shmdt(str);// 删除共享内存段shmctl(shmid,IPC_RMID,nullptr);std::cout<<"共享内存已清理"<<std::endl;return0;}

编译和运行

# 编译写入进程g++ writer.cpp -o writer# 编译读取进程g++ reader.cpp -o reader# 打开两个终端,先运行写入进程./writer# 在另一个终端运行读取进程./reader

Windows下的共享内存(简单示例)

#include<windows.h>#include<iostream>#include<string>intmain(){// 创建共享内存HANDLE hMapFile=CreateFileMapping(INVALID_HANDLE_VALUE,// 使用系统页面文件nullptr,// 默认安全属性PAGE_READWRITE,// 可读可写0,// 高位文件大小256,// 低位文件大小(256字节)L"MySharedMemory");// 共享内存名称// 映射到进程地址空间char*pBuf=(char*)MapViewOfFile(hMapFile,// 共享内存句柄FILE_MAP_ALL_ACCESS,// 可读可写访问0,0,256);// 使用共享内存strcpy(pBuf,"Windows共享内存示例");std::cout<<"写入: "<<pBuf<<std::endl;// 清理UnmapViewOfFile(pBuf);CloseHandle(hMapFile);return0;}

注意事项和最佳实践

  1. 同步问题:多个进程同时访问时需要同步机制(如信号量)
  2. 内存泄漏:确保正确释放共享内存
  3. 安全性:共享内存对所有有权限的进程可见
  4. 大小限制:系统对共享内存大小有限制

常见问题解答

Q: 共享内存和普通内存有什么区别?
A: 共享内存可以被多个进程访问,普通内存只能被创建它的进程访问。

Q: 进程退出后共享内存还在吗?
A: 除非显式删除,否则共享内存会一直存在。

Q: 如何防止数据冲突?
A: 使用同步机制,如互斥锁、信号量等。

Q: 共享内存大小有限制吗?
A: 有,取决于系统配置,通常可以通过系统命令查看和调整。

学习建议

  1. 从简单的示例开始,先理解基本概念
  2. 实践编写两个进程通信的程序
  3. 学习同步机制,处理并发访问
  4. 查阅系统文档,了解具体限制和特性

记住,共享内存是强大的工具,但需要谨慎使用。确保你理解了同步和清理的重要性,避免内存泄漏和数据损坏。祝你学习顺利!

http://www.cnnetsun.cn/news/137428.html

相关文章:

  • 【网络安全】2025新手如何上手挖漏洞(非常详细)零基础入门到精通,看这篇就够了!
  • BurpSuite渗透测试通关手册,简单几步带你从环境配置到报告生成
  • Python | OpenCV | 图像处理 | 入门实验 | 对比度增强 | 裁剪
  • Apifox:API 接口自动化测试完全指南
  • 正反向代理:网络安全核心技术
  • 别被忽悠了!一文讲透MES管理系统本地部署与SaaS模式的真正底牌
  • 【毕业设计】基于springboot+微信小程序的羽球快讯爱好者平台小程序(源码+文档+远程调试,全bao定制等)
  • 小程序计算机毕设之基于SpringBoot的宠物领养微信小程序基于springboot+微信小程序的宠物领养系统小程序(完整前后端代码+说明文档+LW,调试定制等)
  • 小程序计算机毕设之基于springboot+微信小程序的大学生餐厅点餐系统小程序基于springboot微信小程序的校园食堂订餐服务系统(完整前后端代码+说明文档+LW,调试定制等)
  • 计算机小程序毕设实战-基于springboot+微信小程序的影院售票系统设计与实现基于SpringBoot的电影购票平台微信小程序【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 计算机小程序毕设实战-基于springboot+微信小程序的羽球快讯爱好者平台小程序羽毛球场预定app_羽毛球预约管家【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 11、文本与盒子属性的CSS技巧解析
  • 23、WinJS控件样式与样式规则定位指南
  • 27、Windows 8 应用开发中的 SVG 样式设计
  • SAP ABAP拆分交货单数量、批次、存储地点 并过账
  • 基于MPC的智能车运动预测和控制算法 Motion predication; Kinemati...
  • Mathcad的野路子】11kW PFC参数计算书实战拆解
  • STM32学习笔记CAN
  • 搭建你的第一个“私有知识库” (RAG)
  • 13、Unix 系统磁盘管理与安全定位脚本实用指南
  • 15、系统管理脚本实用指南
  • 怎么选一款适合大面积清洁的多功能全自动洗地机呢?
  • 使用matlab编写m脚本,编写无迹卡尔曼滤波算法(UKF)估计电池SOC,注释清晰
  • 教培行业新媒体运营困境凸显!这款软件或成转型制胜法宝?
  • Photoshop Neural Filters:把“引擎截图”秒变“电影级美宣”?AI 深度模糊与色彩迁移工作流
  • 基于matlab的多目标优化算法NSGA3,动态输出优化过程,得到最终的多目标优化结果。 数据...
  • 12.18
  • COCO 数据集
  • 国内好用的测试用例管理工具有哪些?
  • 24、COM+ 事务管理与补偿资源管理器详解