0

0

如何在c++中实现一个跨平台的共享内存IPC? (Boost.Interprocess)

冰火之心

冰火之心

发布时间:2026-01-20 12:47:34

|

326人浏览过

|

来源于php中文网

原创

Boost.Interprocess 能真正跨平台,但需注意Windows与POSIX行为差异:命名机制、权限处理及析构时机不同,其通过封装底层API统一接口,要求开发者关注生命周期管理和进程同步。

如何在c++中实现一个跨平台的共享内存ipc? (boost.interprocess)

Boost.Interprocess 能否真正跨平台?

能,但要注意 Windows 和 POSIX 行为差异。Boost.Interprocess 封装了 shm_open/CreateFileMappingmmap/MapViewOfFile 等底层机制,统一暴露 shared_memory_objectmapped_file 接口。不过 Windows 不支持 POSIX 共享内存的“文件路径式命名”,它用的是内核对象命名空间(如 L"Global\\my_shm"),而 Linux 依赖 /dev/shm/ 下的路径。Boost 会自动适配——只要不用裸系统调用,就无需手动分支。

创建并映射共享内存的最小可行代码

核心是三步:构造 shared_memory_object → 设置大小 → 映射为 mapped_region。注意权限和打开模式必须匹配,否则 Windows 上易报 access denied,Linux 上可能因 /dev/shm 权限或 shm_unlink 残留失败。

#include 
#include 
#include 

namespace bi = boost::interprocess;

// 创建或打开共享内存段(名称需全局唯一) bi::shared_memory_object shm(bi::open_or_create, "MySharedMem", bi::read_write); shm.truncate(65536); // 必须显式设置大小,否则映射失败

// 映射到当前进程地址空间 bi::mapped_region region(shm, bi::read_write); void* addr = region.get_address(); std::size_t size = region.get_size();

如何在共享内存中安全构造 C++ 对象?

直接在 mapped_regionnew 是危险的——析构函数不会被自动调用,且无异常安全保证。正确做法是用 managed_shared_memory,它提供内存池 + 对象生命周期管理:

Lessie AI
Lessie AI

一款定位为「People Search AI Agent」的AI搜索智能体

下载

立即学习C++免费学习笔记(深入)”;

  • managed_shared_memory 内部维护一个类似堆的结构,支持 construct/destroy
  • 所有类型必须是 trivially_copyable 或显式支持 placement new(含自定义构造函数)
  • 避免在共享内存中存放裸指针、std::stringstd::vector ——改用 boost::interprocess::vector 等容器
  • 多进程访问同一对象时,需自行加锁(named_mutexinterprocess_mutex
bi::managed_shared_memory segment(bi::open_or_create, "MySegment", 65536);
// 构造一个 int 并初始化为 42
int* i = segment.construct("MyInt")(42);
// 构造一个共享向量
using ShmVec = bi::vector>>;
ShmVec* vec = segment.construct("MyVec")(segment.get_allocator());

Windows 下常见崩溃点与绕过方式

最常踩的坑是 shared_memory_object 析构时触发 Windows 的 “object busy” 错误(错误码 1732),尤其在调试器附加、进程非正常退出后。根本原因是 Windows 内核对象未被完全释放,而 Boost 默认在析构时尝试 CloseHandle + UnmapViewOfFile,但若其他进程仍在映射,就会失败。

  • 确保每个进程只调用一次 mapped_region::unmap(),且不重复析构 mapped_region
  • 避免在全局对象或 atexit 中清理共享内存;改用 RAII + 显式 segment.destroy("Name")
  • 开发期可临时启用 BOOST_INTERPROCESS_DISABLE_FORCE_DESTRUCTION 宏跳过强制销毁逻辑
  • 生产环境建议用 named_mutex 协调首次创建者执行 segment.destroy,而非依赖析构

跨平台 IPC 的复杂性不在 API 调用本身,而在共享状态的生命周期管理——谁创建、谁销毁、谁负责同步、谁处理残留。Boost.Interprocess 把系统差异藏好了,但没把并发模型藏起来。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

318

2023.08.02

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1025

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

66

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

451

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

10

2026.01.19

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

392

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

601

2023.07.26

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

0

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.5万人学习

Git 教程
Git 教程

共21课时 | 2.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号