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

http://blog.csdn.net/anonymalias/article/details/50496563

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

<code class="language-c++ hljs vala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <boost/interprocess/file_mapping.hpp></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

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

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

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

<code class="language-c++ hljs vala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <boost/interprocess/managed_mapped_file.hpp></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

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简单的类图关系: 
这里写图片描述

当需要在一个托管内存段(这里不止使用于mapped file,也同样试用共享内存,堆内存)上构建一个具名对象,boost ipc提供了construct 和find_or_construct接口。 
我们可以直接调用managed_mapped_file的这两个成员进行对象的构造,由上面的类图关系可知,对象的构造最终依赖与segment_manager

那么segment_manager是如何工作的呢? 
managed_mapped_file的segment_manager等同于allocator,那么其工作原理其实就是简单的分为两个过程:

  • 内存的分配和释放
  • 对象的构造和销毁

managed_mapped_file对象在创建的时候,会初始化它本身的segment_manager.

<code class="language-c++ hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">typedef typename segment_manager_<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">type</span>
      <CharType, MemoryAlgorithm, IndexType>::<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">type</span>    segment_manager;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

segment_manager字面意思为段管理器。其实它本质上也就是一个allocator空间配置器,它全权负责内存映射文件对应到的进程空间地址的分配和管理。这就是前面我啰嗦那么多stl allocator的概念的原因. Segment_manager的核心是MemoryAlgorithm,MemoryAlgorithm负责内存的分配和销毁,它的实现是在managed_mapped_file在创建的时候传入的,如下。

<code class="language-c++ hljs d has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> basic_managed_mapped_file
   <<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">char</span>
   ,rbtree_best_fit<mutex_family>
   ,iset_index>
managed_mapped_file;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

默认的managed_mapped_file在创建的时候,采用的内存管理算法rbtree_best_fit对segment_manager进行初始化,这个算法很高级。。。通过rb对空闲内存块排序,时间复杂度在lgn。这里先不深揪了,和free list算法比,由于没有看rbtree_best_fit的实现,表象上来看free list的时间复杂度是O(1),至于内存碎片什么的,应该不如rbtree_best_fit。

所以说segment_manager是managed_mapped_file的核心。 
这里就不画segment_manager的类图了,简单的截了si的成员列表: 
这里写图片描述 
segment_manager实现了allocator类最基本的四个成员:allocate()&deallocate(), construct()&destroy()。用于内存的分配和释放,对象的构建和销毁。

好了,说到这里,上一段代码吧:

<code class="language-c++ hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include <iostream></span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include <boost/interprocess/allocators/node_allocator.hpp></span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include <boost/interprocess/managed_mapped_file.hpp></span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include <boost/interprocess/containers/map.hpp></span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include <boost/interprocess/containers/string.hpp></span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include <boost/interprocess/containers/vector.hpp></span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include <boost/interprocess/offset_ptr.hpp></span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include <boost/container/string.hpp></span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include <boost/lexical_cast.hpp></span>

namespace bipc = <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:boost</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:interprocess</span>;
typedef <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">bipc:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:managed_mapped_file</span> managed_mapped_file_t;
typedef <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">bipc:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:managed_mapped_file</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:segment_manager</span> mapped_segment_manager_t;

typedef <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">bipc:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:node_allocator<float</span>, mapped_segment_manager_t> vec_allocator_t;
typedef <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">bipc:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:vector<float</span>, vec_allocator_t> vector_t;

struct <span class="hljs-constant" style="box-sizing: border-box;">Msg</span>
{
    <span class="hljs-constant" style="box-sizing: border-box;">Msg</span>(const vec_allocator_t &vec_alloc) <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span> score(vec_alloc){}

    uint32_t id;
    uint32_t age;
    vector_t score;
};

typedef <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">std:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:pair<const</span> uint32_t, <span class="hljs-constant" style="box-sizing: border-box;">Msg</span>> pair_t;
typedef <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">bipc:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:node_allocator<pair_t</span>, mapped_segment_manager_t> allocator_t;
typedef <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">std:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:less<uint32_t></span> less_t;

typedef <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">bipc:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:map<uint32_t</span>, <span class="hljs-constant" style="box-sizing: border-box;">Msg</span>, less_t, allocator_t> msg_map_t;
typedef <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">msg_map_t:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:iterator</span> map_iter_t;

int main()
{
    managed_mapped_file_t obj_mapped_file(<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">bipc:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:open_or_create</span>, \
            <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"./msg_map_vector_construct.mmap"</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1024</span>*<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1024</span>);
    msg_map_t *p_msg_map = obj_mapped_file.find_or_construct<msg_map_t>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msg_map"</span>)(\
            less_t(), obj_mapped_file.get_segment_manager());
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-constant" style="box-sizing: border-box;">NULL</span> == p_msg_map)
    {
        <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">std:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:cerr<<<span class="hljs-string" style="box-sizing: border-box;">"construct msg_map failed"</span><<std</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:endl</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
    }

    vec_allocator_t obj_alloc(obj_mapped_file.get_segment_manager());

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(int i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>; ++i)
    { 
        map_iter_t itr = p_msg_map->find(i);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(itr == p_msg_map-><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">end</span>())
        {
            <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">std:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:cout<<<span class="hljs-string" style="box-sizing: border-box;">"not find:"</span><<i<<<span class="hljs-string" style="box-sizing: border-box;">" insert:"</span><<i<<std</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:endl</span>;

            <span class="hljs-constant" style="box-sizing: border-box;">Msg</span> msg(obj_alloc);
            msg.id = i;
            msg.age = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span> +i;
            msg.score.push_back(i);
            msg.score.push_back(i + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);

            p_msg_map->insert(<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">std:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:pair<uint32_t</span>, <span class="hljs-constant" style="box-sizing: border-box;">Msg</span>>(i, msg));
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
        {
            <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">std:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:cout<<<span class="hljs-string" style="box-sizing: border-box;">"find:"</span><<i<<<span class="hljs-string" style="box-sizing: border-box;">" data:"</span><<itr->second</span>.age;
            <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">std:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:cout<<<span class="hljs-string" style="box-sizing: border-box;">" score:"</span></span>;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(int j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; j < itr->second.score.size(); ++j)
                <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">std:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:cout<<itr->second</span>.score[j]<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" "</span>;
            <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">std:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:cout<<std</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:endl</span>;
        }
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li></ul>

现在解释代码中的关键结构:

在managed_mappped_file上构建boost::interprocess容器时,容器的allocator模版参数一定要传入managed_mappped_file::segment_manager。这个原因就是本文的阐述:当对容器对象进行构建的时候,需要在mapped_file 的地址空间进行对象的构造,因为managed_mappped_file的内存分配和对象构造都是由segment_manager负责的,所以有示例代码:

<code class="language-c++ hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> bipc::node_allocator<<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span>, mapped_segment_manager_t> vec_allocator_t;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> bipc::<span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span>, vec_allocator_t></span> vector_t;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> bipc::node_allocator<pair_t, mapped_segment_manager_t> allocator_t;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> bipc::<span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span><uint32_t, Msg, less_t, allocator_t></span> msg_map_t;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

如果struct Msg为POD类型,Msg就不需要下面那个构造函数,但Msg中含有vector_t 
.当Msg对象在构造的时候,需要递归调用成员vector_t score的构造函数进行score对象的构造,这个时候是肯定需要知道vector_t的allocator对象的,所以需要传入vec_allocator_t的对象。

<code class="language-c++ hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> Msg
{
    Msg(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> vec_allocator_t &vec_alloc) : score(vec_alloc){}
    uint32_t id;
    bipc::<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> name;
    uint32_t age;
    vector_t score;
};</code>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值