news 2026/7/2 15:31:50

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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. 查阅系统文档,了解具体限制和特性

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 1:32:41

BurpSuite渗透测试通关手册,简单几步带你从环境配置到报告生成

在Web应用安全测试中&#xff0c;Burp Suite被誉为“渗透测试的瑞士军刀”&#xff0c;其强大的扫描功能能高效挖掘SQL注入、XSS、信息泄露等漏洞。本文将结合实战步骤&#xff0c;详细解析如何利用Burp Suite进行安全扫描&#xff0c;助你快速掌握核心技巧&#xff01; 一、扫…

作者头像 李华
网站建设 2026/6/29 21:08:46

Python | OpenCV | 图像处理 | 入门实验 | 对比度增强 | 裁剪

0. 前言 “图像处理”听起来高大上&#xff0c;其实用 20 行 Python 就能跑起来。 今天带大家在 10 分钟 内完成一次真实可跑的实验&#xff1a;把一张机器人照片 robot.jpg 切成左上角&#xff1b;再把亮度 / 对比度拉满&#xff1b;最后保存成新图 robot_enhanced.jpg。读完你…

作者头像 李华
网站建设 2026/7/1 18:34:27

Apifox:API 接口自动化测试完全指南

01 前言 这是一篇关于 Apifox 的接口自动化测试教程。相信你已经对 Apifox 有所了解&#xff1a;“集 API 文档、API 调试、API Mock、API 自动化测试&#xff0c;更先进的 API 设计/开发/测试工具”。 笔者是后端开发&#xff0c;因此这篇教程关注的是 API 自动化测试&#…

作者头像 李华
网站建设 2026/6/29 22:17:43

正反向代理:网络安全核心技术

一、核心概念&#xff1a;定义与本质区别1. 正向代理&#xff08;Forward Proxy&#xff09;定义&#xff1a;客户端与目标服务器之间的 “中介代理”&#xff0c;客户端主动配置代理服务器后&#xff0c;所有请求先发送至代理&#xff0c;再由代理转发至目标服务器&#xff0c…

作者头像 李华
网站建设 2026/7/1 5:46:24

别被忽悠了!一文讲透MES管理系统本地部署与SaaS模式的真正底牌

“我们要上MES&#xff0c;但老板觉得一次性投入几百万太贵了&#xff0c;听说有那种每年交几万块的云MES&#xff0c;能不能用&#xff1f;”这是过去两年里&#xff0c;我被问到频率最高的问题&#xff0c;没有之一。大家好&#xff0c;我是老李。在制造业摸爬滚打了10年&…

作者头像 李华