Boost:managed_mapped_file及C++内存分配和对象构造分析

本文深入探讨了Boost的managed_mapped_file接口,它简化了内存映射文件上的对象构造。文章介绍了C++的allocator原理,强调了managed_mapped_file如何在内存映射文件上构建对象,以及segment_manager在内存分配和对象构造中的作用。同时,文章指出在使用managed_mapped_file构建容器时,需要传入segment_manager作为allocator。

Boost的提供了一套ipc的接口,内存映射文件将文件的内容映射到进程的地址空间。

#include <boost/interprocess/file_mapping.hpp>

原生的file_mapping接口提供了创建一个内存映射文件,然后通过mapped_region进行进程地址空间的映射,获取映射到进程空间的地址,并在此地址进行对象的构造和操作。

由于直接在映射的地址进行复杂数据结构的构造很复杂的事情,原因是:映射后只能获得一个起始地址,要在这个地址上进行对象的构建和销毁,都要基于这个地址,也就是所构建的对象内部必须都是相对地址,不能使用现有的stl的容器,因为他们都是构建在堆上的,内存使用的都是指针,不是一个偏移。

所以boost提供了更高层次的接口managed_mapped_file

#include <boost/interprocess/managed_mapped_file.hpp>

managed_mapped_file允许在内存映射文件上直接构建复杂的boost的数据结构。是不是很兴奋。。。
Managed_mapped_file不能在map file上构建STL的容器。和原生的file_mapping一样,托管内存映射文件类只是隐藏了在映射空间上构建对象的细节,它本身依然是基于一个映射起始地址的字节操作。内部使用的都是相对偏移地址,所以不能使用STL容器。

在使用managed_mapped_file进行数据结构构造之前,要知道:

  • Allocator:的含义和工作原理
  • Managed_mapped_file的接口含义

在C++的stl中,allocator作为所有容器的标配,负责所有数据结构的动态内存的分配和销毁、对象的构造和析构。和new表达式的功能可以理解为一样的。那这里理一下C++的内存分配。
new表达式执行过程:

  • 首先会调用operator new这个标准库函数,分配足够的原始未类型化的内存
  • 然后调用该类型的构造函数进行对象的构造
  • 最后返回对象的指针

new表达式执行过程中内存分配和对象的构造是无法分开的。但有时候我们希望内存的分配和对象的构造进行分离。因为new可能在某些类的创建过程中带来很多运行时的开销。具体原因有如下:

  • 可能会创建从不使用的对象
  • 使用预先分配对象的时候,被使用的对象必须重新赋值
  • 若预分配的内存必须被构造,某些类就不能使用它。

基于上面的理由,就出现了动态内存的预分配技术,即allocator。allocator类中allocate()和deallocate()成员负责内存的分配,construct()和destroy()负责对象的构造和销毁。”
C++标准中的allocator类主要包含以下4个成员:
这里写图片描述

引用C++ primer中的一句话

现代C++程序一般应该使用allocator类来分配内存,它更安全更灵活。

至于allocator的实现,在SGI STL中,标准的allocator类内存使用operator new和operator delete进行内存的分配和释放。特殊的allocator(所有stl 容器默认使用的),采用的二级配置器,分配算法采用:内存池 + free list, 内存的分配采用c的malloc和free。这里就不细说了。

说到这里allocator的功能和用途也很清楚了。

那么现在看一下managed_mapped_file简单的类图关系:
这里写图片描述

当需要在一个托管内存段(这里不止使用于ma

`boost::interprocess::managed_shared_memory` 是 Boost 库中用于在多个进程间实现共享内存管理的工具,提供了一种在共享内存区域分配管理对象的方式,适合多进程间的数据共享与通信。 ### 原理 `boost::interprocess::managed_shared_memory` 通过操作系统提供的共享内存机制创建管理一块可被多个进程访问的内存区域。该机制允许不同进程将同一块物理内存映射到各自的虚拟地址空间,实现数据的共享。同时,`managed_shared_memory` 提供了内存管理功能,允许在共享内存中动态分配释放对象,还支持对这些对象的同步访问,确保多进程环境下的数据一致性。 ### 使用方法 1. **包含头文件**:使用 `#include <boost/interprocess/managed_shared_memory.hpp>` 引入必要的头文件。 2. **创建或打开共享内存**:使用 `managed_shared_memory` 的构造函数创建或打开共享内存区域。构造函数可以指定是创建新的共享内存、打开已有的共享内存,或者在不存在时创建、存在时打开。 3. **分配释放内存**:使用 `allocate` 方法在共享内存中分配对象,使用 `deallocate` 方法释放分配的内存。 4. **存储访问对象**:在分配的内存中存储访问对象,可以使用指针操作或者类型转换。 5. **同步访问**:为确保多进程环境下的数据一致性,可能需要使用同步机制,如互斥锁、信号量等。 6. **删除共享内存**:使用 `shared_memory_object::remove` 静态方法删除共享内存区域。 ### 示例代码 ```cpp #include <boost/interprocess/managed_shared_memory.hpp> #include <iostream> #include <cstring> int main() { using namespace boost::interprocess; try { // 创建一个名为 "MySharedMemory" 的共享内存区域,大小为 65536 字节 managed_shared_memory segment(create_only, "MySharedMemory", 65536); // 在共享内存中分配一个整数对象 int *shared_int = segment.construct<int>("MyInteger")(10); // 在共享内存中分配一个字符数组 char *shared_string = segment.construct<char>("MyString")[100](); // 向共享字符数组中写入数据 std::strcpy(shared_string, "Hello, shared memory!"); // 输出共享内存中的整数字符串 std::cout << "Shared integer: " << *shared_int << std::endl; std::cout << "Shared string: " << shared_string << std::endl; // 释放共享内存中的对象 segment.destroy<int>("MyInteger"); segment.destroy<char>("MyString"); } catch (interprocess_exception &ex) { std::cerr << "Exception: " << ex.what() << std::endl; return 1; } // 删除共享内存区域 shared_memory_object::remove("MySharedMemory"); return 0; } ```
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值