Windows用CreateFileMapping+MapViewOfFile、Linux用shm_open+mmap实现共享内存,二者均需注意大小设置、错误处理、同步机制及跨平台兼容性,且共享内存中不可存放std::string等非平凡类型。
CreateFileMapping 和 MapViewOfFile 创建共
享内存Windows 原生共享内存依赖内存映射文件(Memory-Mapped File),即使不关联磁盘文件,也能通过 INVALID_HANDLE_VALUE 创建纯内存段。关键不是“文件”,而是“映射对象”。
常见错误是传错 dwMaximumSizeHigh/dwMaximumSizeLow —— 它们合起来是 64 位大小,但多数场景用不到高位,直接设为 0 即可;若实际大小超 4GB,才需拆分赋值。
CreateFileMapping 返回 NULL 时,务必调用 GetLastError() 判断原因:权限不足(ERROR_ACCESS_DENIED)、名字冲突(ERROR_ALREADY_EXISTS)或内存不足(ERROR_NOT_ENOUGH_MEMORY)都得区分处理hMap 有效,且 MapViewOfFile 的 dwNumberOfBytesToMap 不能超过创建时声明的大小CreateEvent 或 CreateMutex 控制读写顺序HANDLE hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024, TEXT("MySharedMem"));
if (hMap == NULL) {
// 处理错误
}
LPVOID pMem = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 1024);
if (pMem == NULL) {
CloseHandle(hMap);
}shm_open + mmap 创建 POSIX 共享内存Linux 推荐用 POSIX 标准接口:shm_open 创建/打开一个共享内存对象(本质是 /dev/shm/ 下的虚拟文件),再用 mmap 映射进地址空间。它比 sysv shm(shmget 系列)更现代、路径可控、权限清晰。
容易忽略的是 shm_open 的 oflag 参数:跨进程通信必须带 O_RDWR,首次创建还要加 O_CREAT;同时 mode(如 0666)决定其他用户能否打开——若不设,可能被 umask 截断导致权限不足。
shm_open 返回的 fd 必须在 mmap 后 close(),否则资源泄漏(fd 不释放,但映射仍有效)mmap 的 length 必须与 ftruncate 设置的大小一致,否则读写越界或 SEGV
shm_unlink(仅删除名字,已映射的仍可用)int fd = shm_open("/my_shm", O_CREAT | O_RDWR, 0666);
ftruncate(fd, 1024);
void* ptr = mmap(nullptr, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd); // fd 可关,ptr 仍有效Windows 和 Linux 的共享内存 API 差异大,强行抽象成统一接口容易踩坑。最现实的做法是按平台条件编译,或只封装“创建/映射/销毁”三步,把同步逻辑完全交给上层。
典型陷阱包括:
"MyMem"),Linux 的 shm_open 要求以 / 开头且不能含其它斜杠("/my_mem" 合法,"/a/b" 非法)/dev/shm 大小常为 64MB,可通过 mount -o remount,size=2G /dev/shm 调整shm_unlink 类似于 Windows 的 CloseHandle + 名字注销,但 Windows 没有等价的“仅删名不关句柄”操作std::string 或虚函数对象共享内存本质是一段裸字节区域,所有数据必须是 trivially copyable,且地址无关。一旦结构体里包含 std::string、std::vector、指针、虚表指针或非 POD 成员,就绝不能直接 memcpy 进去。
例如:struct Data { std::string name; int id; }; —— name 内部指针指向堆内存,其他进程无法访问;虚函数对象的 vptr 指向本进程的虚表,跨进程失效。
char name[64])、手动序列化、或使用 boost::interprocess 提供的容器(如 boost::interprocess::basic_string)alignas(8)),避免不同编译器填充差异导致读写错位共享内存本身不难创建,难的是让两个独立进程安全、稳定、一致地解释同一片内存里的比特。类型布局、生命周期、同步粒度,这三样漏掉任何一环,都会在某个并发时机突然崩掉。
# linux
# windows
# app
# 字节
# access
# c++
# win
# nas
# 同步机制
# 为什么
# red
# asic
# String
# NULL
# 封装
# 字符串
# 结构体
# char
# int
# 指针
# 虚函数
# 接口
# 堆
# Length
# Struct
# 并发
# 对象
# 的是
# 首次
# 多个
# 句柄
# 也能
# 设为
# 要注意
# 再用
# 可通过
# 都得
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
Win10怎样清理C盘Steam游戏缓存_Win10清理Steam游戏缓存步骤【步骤】
Win11怎么关闭内容自适应亮度_Windows11显示设置CABC关闭
Win11任务栏颜色怎么改_Win11自定义任务栏配色设置【美化】
Win11如何设置开机问候语 Win11修改登录界面提示【技巧】
C++如何使用std::async进行异步编程?(future用法)
php本地部署后session无法保存_session存储路径与权限设置技巧【技巧】
本地php环境出现502错误_nginx或apache502badgateway解决技巧【解答】
win11 OneDrive怎么彻底关闭 Win11禁用并卸载OneDrive教程【分享】
php增删改查在php8里有什么变化_新特性对curd的影响【指南】
Windows Defender扫描失败怎么办_安全模块损坏修复方式
如何在 Go 中正确反序列化 XML 多节点数组(解决仅解析首个元素的问题)
Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤
php串口通信波特率怎么选_根据硬件手册设置正确波特率【方法】
Django密码修改后会话失效的解决方案
Win11怎么开启专注模式_Windows11时钟应用Focus Session
如何在Golang中使用encoding/gob序列化对象_存储和传输数据
Python对象比较与排序_魔术方法解析【教程】
phpstudy本地环境mysql忘记密码_重置mysqlroot密码操作流程【解答】
Win11怎么打开旧版计算器_Win11恢复传统计算器应用【详解】
Windows系统文件被保护机制阻止怎么办_权限不足错误处理方案
mac怎么分屏_MAC双屏显示与分屏操作技巧【指南】
Win11怎么设置虚拟键盘_打开Win11屏幕键盘操作指南【技巧】
如何在 Django 中安全修改用户密码而不使会话失效
Windows10怎么用“讲述人”读屏辅助 Windows10轻松使用开启讲述人朗读屏幕文字帮助视障用户【教程】
Windows7如何安装系统镜像_Windows7系统安装教程【步骤】
php8.4匿名类怎么用_php8.4匿名类创建与使用场景【介绍】
如何在 PHP 单元测试中正确模拟带方法的图像处理门面(Facade)
如何在Golang中捕获结构体方法错误_Golang方法返回error处理实践
Win10怎样设置多显示器_Win10多显示器扩展设置【攻略】
Windows10系统怎么查看显卡驱动_Win10设备管理器驱动更新
Win11怎么设置按流量计费_Win11限制后台流量消耗【网络】
php怎么下载安装并配置环境变量_命令行调用PHP技巧【技巧】
如何使用Golang配置安全开发环境_防止敏感信息泄露
如何在Golang中实现基础配置管理功能_Golang配置文件读取与更新示例
php增删改查报错1054怎么办_字段名错误排查修复【解答】
PythonFastAPI项目实战教程_API接口与异步处理实践
Win11怎么退出微软账户_切换Win11为本地账户登录方法【详解】
如何使用正则表达式提取以编号开头、后接多个注解的逻辑分组块
php订单日志怎么按金额排序_php按订单金额排序日志方法【方法】
mac怎么查看wifi密码_MAC查看已连接WiFi密码方法【技巧】
MAC怎么在照片中添加水印_MAC自带编辑工具文字水印叠加【方法】
Win11怎么设置环境变量_Win11配置Path路径变量【详解】
如何使用Golang table-driven基准测试_多组数据测量函数效率
Windows 10怎么录屏_Windows 10使用Xbox Game Bar录制屏幕视频教程
Win11怎么解压RAR文件 Win11自带解压功能使用方法
PHP cURL GET请求:正确设置请求头与身份认证的完整教程
c++ try_emplace用法_c++ map高效插入数据
Win11怎么设置默认浏览器Chrome_Windows11修改默认网页打开方式
微信里的php文件怎么变mp4_微信接收php转mp4操作步骤【操作】
Win11如何更改用户账户文件夹名称 Win11修改C:Users用户名【终极教程】
2026-01-02
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。