C++boost库之共享内存interprocess
Linux下的安装
安装vcbkg
准备工作:安装基础构建工具
无论您选择哪种方法,都需要先安装 C++ 编译器、CMake 和 Git。
打开终端,执行以下命令:
# 1. 更新软件包列表
sudo apt update
# 2. 安装必要的构建工具
# build-essential 包含 g++ 编译器、make 等 # cmake 是现代 C++ 项目首选的构建系统
# git 用于下载源码
sudo apt install build-essential cmake git -y
正式安装
# 1. 克隆 vcpkg 仓库到你选择的目录(例如 ~/.vcpkg 或 /opt/vcpkg)
# 这里我们选择放在用户主目录下
git clone https://github.com/microsoft/vcpkg.git ~/.vcpkg
# 2. 运行 vcpkg 的引导脚本来编译它自身
~/.vcpkg/bootstrap-vcpkg.sh
配置vcpkg环境变量
步骤 1: 打开配置文件
使用你喜欢的文本编辑器打开 ~/.bashrc 文件。这里以 nano 为例(比较简单易用):
nano ~/.bashrc
步骤 2: 添加配置
在文件的末尾,添加下面这行代码:
export PATH="/root/.vcpkg:$PATH"
(可选但强烈建议)
为了更好地与 CMake 等工具集成,vcpkg 官方推荐同时设置 VCPKG_ROOT 环境变量。你可以这样写,更规范:
# Add vcpkg to environment export VCPKG_ROOT=~/.vcpkg export PATH="$VCPKG_ROOT:$PATH"
export VCPKG_ROOT=~/.vcpkg定义了 vcpkg 的根目录。export PATH="$VCPKG_ROOT:$PATH"使用上一步定义的变量来设置 PATH,更清晰且易于维护。
步骤 3: 保存并退出
- 在
nano编辑器中,按Ctrl + O保存文件(会提示你确认文件名,直接按回车即可)。 - 然后按
Ctrl + X退出编辑器。
步骤 4: 让配置立即生效
新配置只会在下次登录或打开新终端时生效。要让它在当前终端立即生效,执行以下命令
source ~/.bashrc
验证是否安装成功
vcpkg --version
如果能看到版本信息,说明已经配置成功。
现在,你就可以在任何目录下直接使用 vcpkg 命令
安装boost-interprocess
使用vcbkg安装interprocess
使用vcpkg进行安装非常简单,vcpkg会自动帮我们进行安装对应的依赖
~/.vcpkg/vcpkg install boost-interprocess
验证安装
vcpkg list | grep interprocess

如果像上图这样能够进行打印interprocess库的相关信息,这样的话就证明安装成功了。
boost.interprocess库的概述
从这个库的名字就可以看出来这个库是用于进程间通信的,这个库的本质就是通过共享内存和同步原语提供进程间的通信的。
简单的说就是:Boost.Interprocess 不仅为你提供了创建“共享白板”(共享内存)的能力,还为你提供了管理这块白板使用秩序的“规则和工具”(如互斥锁、信号量等同步原语),从而让你能够安全、可靠地在多个进程之间共享和操作数据,避免出现混乱和错误。
Boost.Interprocess 提供了可以在进程间使用的同步原语,以下是几个典型的例子:
互斥锁 (Mutex):
- 作用:就像我们比喻中的那把“钥匙”。它是最基本、最常用的同步原语。一个进程在访问共享数据前先“锁定”(lock)互斥锁,访问结束后再“解锁”(unlock)。如果一个进程尝试锁定时发现互斥锁已被其他进程锁定,它就会被阻塞(等待),直到那个进程解锁。
- Boost.Interprocess 中的对应物:
boost::interprocess::interprocess_mutex。信号量 (Semaphore):
作用:是互斥锁的“升级版”。互斥锁只允许一个进程访问,而信号量可以允许多个(但有数量限制)进程同时访问资源。
- 比喻:就像一个停车场有 10 个车位。入口处的显示屏显示剩余车位数。每进去一辆车,车位数减 1;每出来一辆,加 1。当车位数为 0 时,后来的车就必须在外面排队等待。
- Boost.Interprocess 中的对应物:
boost::interprocess::interprocess_semaphore。条件变量 (Condition Variable):
- 作用:用于让一个进程等待某个特定“条件”的发生。它通常和互斥锁一起使用,可以避免进程在等待时不停地检查条件(这种行为称为“忙等待”,非常消耗 CPU)。
- 比喻:就像你在等快递。你不会每分钟都去门口看快递员来了没有,而是告诉快递员:“到了就按门铃”。你(进程)去“睡觉”(等待),门铃(条件变量)响了,你才被“唤醒”去开门(继续执行)。
- Boost.Interprocess 中的对应物:
boost::interprocess::interprocess_condition。文件锁 (File Lock):
- 作用:专门用于协调不同进程对同一个文件的访问。
- Boost.Interprocess 中的对应物:
boost::interprocess::file_lock。
boost.interprocess库的主要功能
提供可移植的、适合 C++ 的抽象层来简化特定于平台的功能的使用,用于在进程之间共享内存、同步对共享资源的访问以及在共享内存区域中构建 C++ 对象。

boost.Interprocess 提供了一套全面的 IPC 机制:
- 共享内存对象和内存映射文件
- 进程同步基元(互斥体、信号量、条件变量)
- 命名同步对象(类似于 UNIX/Windows sem_open/CreateSemaphore API)
- 文件锁定机制
- 用于跨进程指针安全的偏移指针
- 用于数据交换的消息队列
- 与共享内存兼容的类 STL 容器和分配器
- 共享内存段的内存分配模式
Boost.Interprocess 内存管理与 segment_manager
在 boost::interprocess 中,共享内存的核心管理组件就是 segment_manager(段管理器)。理解它是正确使用共享内存的关键。
一、segment_manager 的作用
segment_manager 是共享内存的“操作系统”,它管理着整个内存段中的对象和内存分配。主要职责包括:
-
内存管理中枢
负责共享内存段中所有的内存分配、对象构造与析构。 -
智能内存管理
能够追踪共享内存中分配的内存块和对象,避免传统裸指针式的内存泄漏风险。 -
持久化支持
即使进程退出,共享内存段依然存在(直到显式删除),管理的信息可供其他进程继续使用。
二、segment_manager 的工作原理
#include <boost/interprocess/managed_shared_memory.hpp>
namespace bip = boost::interprocess;
typedef bip::managed_shared_memory::segment_manager segment_manager_t;
// 创建托管共享内存
bip::managed_shared_memory segment(
bip::open_or_create, "my_shared_memory", 65536);
// 获取段管理器
segment_manager_t* manager = segment.get_segment_manager();
// 使用段管理器创建对象
int* number = manager->construct<int>("my_number")(42); //创建一个int大小的内存对象并将其赋值为42
✅ 注意:通过
manager->construct创建的对象,会带有名字"my_number",后续可以在进程间通过名字查找。
段管理器 construct:创建一个对象,并完成初始化和命名。
-
适用场景:
-
想要跨进程共享的命名对象
-
想要自动管理构造/析构的对象
-
三、内存分配算法与分配器
boost::interprocess 的托管内存类(如 managed_shared_memory)会基于 segment_manager 提供分配器(allocator),从而支持 STL 风格的容器。
1. 基础分配器
共享内存分配器本质上是一个包装器,利用 segment_manager 在共享内存中申请内存。
typedef bip::allocator<void, segment_manager_t> void_allocator;
// 创建分配器
void_allocator alloc(manager);
// 分配原始内存(单位是对象个数,而非字节)
void* raw_memory = alloc.allocate(1024); // 分配 1024 个 void 单位
// 使用完后释放
alloc.deallocate(raw_memory, 1024);
⚠️ 常见误区
allocate(1024)这里的参数并不是字节数,而是“对象个数”。
对allocator<void>来说,相当于字节,但如果是allocator<int>就是分配 1024 个int。
分配器 allocate:分配一块原始内存(像 new[])但是是在共享内存中进行分配的,但不会自动构造。
-
适用场景:
-
自定义对象池
-
需要与 STL 容器(
vector,map等)配合使用
-
典型用途:共享内存容器(vector, map, string)
2. 专门分配字符串存储
typedef bip::allocator<char, segment_manager_t> char_allocator;
char_allocator char_alloc(manager);
// 分配字符数组(注意 allocate 的单位是 char,而不是字节)
char* text = char_alloc.allocate(256);
strcpy(text, "hello shared memory");
// 使用后释放
char_alloc.deallocate(text, 256);
简单的总结:
无论是使用段管理器进行创建内存对象还是使用内存分配器进行分配原始内存,都需要进行创建共享内存和获取共享内存的句柄。
五、共享内存中的容器
在 进程内,我们可以直接用
std::string和std::vector等 STL 容器。
但在 跨进程共享内存 的场景里,这些容器内部会调用进程堆分配器(std::allocator),而堆是进程私有的,另一个进程访问时会崩溃。所以 Boost.Interprocess 提供了 替代品:
共享字符串:
boost::interprocess::basic_string共享容器:
boost::interprocess::vector,map,list,set…
它们都通过 共享内存分配器(allocator) 从共享内存段里分配内存,从而能在多个进程间使用。
1.Boost.Interprocess string
Boost 提供 basic_string 的共享内存版本,需要配合 allocator<char> 使用。
// 1. 创建或打开共享内存段
bip::managed_shared_memory segment(
bip::open_or_create, "MyAppSharedMemory", 1024 * 1024);
// 2. 获取段管理器
auto manager = segment.get_segment_manager();
// 3. 创建字符分配器
bip::allocator<char, decltype(manager)> char_alloc(manager);
// 4. 定义共享字符串类型
typedef bip::basic_string<char, std::char_traits<char>, decltype(char_alloc)>
shared_string;
// 5. 在共享内存中创建或查找字符串对象
shared_string* app_data = segment.find_or_construct<shared_string>
("AppData")("Initial Value", char_alloc);
// 6. 使用字符串
*app_data = "Updated Value: " + std::to_string(42);
std::cout << "Shared string: " << *app_data << std::endl;
功能
-
存储和操作文本数据,接口与
std::string基本一致:支持拼接、比较、拷贝、迭代器等。 -
内存来自共享内存段,而不是进程私有堆。
-
可以用
segment.find_or_construct在共享内存中命名和构造字符串对象。
用途
-
共享状态信息
例如,一个进程写"READY",另一个进程读取"READY"判断系统状态。 -
日志/消息传递
把"Error at step 42"存到共享内存中,供监控进程读取。 -
共享配置
配置项(例如"mode=debug")存放在共享内存中,多个进程可随时读取。
2.Boost.Interprocess 容器(vector, map, list, …)
Boost.Interprocess 容器(如 vector, map 等)都需要使用基于 segment_manager 的分配器。
// 定义分配器
typedef bip::allocator<ShmPdoInfo, segment_manager_t> ShmPdoInfoAllocator;
// 定义共享内存 vector
typedef bip::vector<ShmPdoInfo, ShmPdoInfoAllocator> ShmPdoInfoVector;
这样就可以在共享内存中直接存放 STL 风格的容器,多个进程间共享数据。
功能
-
提供 STL 容器的共享内存版本:
-
vector<T, Alloc> -
list<T, Alloc> -
map<Key, T, Compare, Alloc> -
set<T, Compare, Alloc>
-
-
支持常规 STL 接口:插入、删除、迭代。
-
所有内存来自共享内存段。
-
可与
find_or_construct配合,保证跨进程可访问。
用途
-
共享队列 / 消息缓冲区
用vector或list存放待处理消息,多个进程读写。 -
共享缓存 / 索引表
用map存放数据索引,比如map<string, Data>,进程 A 写入,进程 B 直接查找。 -
共享实时数据
存放传感器采样、行情数据、网络包等,多个进程同时消费。
更多推荐
所有评论(0)