UNPKG

boost-react-native-bundle

Version:

Boost library as in https://sourceforge.net/projects/boost/files/boost/1.57.0/

537 lines (509 loc) 201 kB
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> <title>Allocators, containers and memory allocation algorithms</title> <link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css"> <meta name="generator" content="DocBook XSL Stylesheets V1.78.1"> <link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset"> <link rel="up" href="../interprocess.html" title="Chapter&#160;14.&#160;Boost.Interprocess"> <link rel="prev" href="managed_memory_segments.html" title="Managed Memory Segments"> <link rel="next" href="memory_algorithms.html" title="Memory allocation algorithms"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> <table cellpadding="2" width="100%"><tr> <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td> <td align="center"><a href="../../../index.html">Home</a></td> <td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> <td align="center"><a href="../../../more/index.htm">More</a></td> </tr></table> <hr> <div class="spirit-nav"> <a accesskey="p" href="managed_memory_segments.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../interprocess.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="memory_algorithms.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> </div> <div class="section"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> <a name="interprocess.allocators_containers"></a><a class="link" href="allocators_containers.html" title="Allocators, containers and memory allocation algorithms">Allocators, containers and memory allocation algorithms</a> </h2></div></div></div> <div class="toc"><dl class="toc"> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.allocator_introduction">Introduction to Interprocess allocators</a></span></dt> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_segregated_storage">Segregated storage node allocators</a></span></dt> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_adaptive">Adaptive pool node allocators</a></span></dt> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.containers_explained">Interprocess and containers in managed memory segments</a></span></dt> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.additional_containers">Boost containers compatible with Boost.Interprocess</a></span></dt> </dl></div> <div class="section"> <div class="titlepage"><div><div><h3 class="title"> <a name="interprocess.allocators_containers.allocator_introduction"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.allocator_introduction" title="Introduction to Interprocess allocators">Introduction to Interprocess allocators</a> </h3></div></div></div> <div class="toc"><dl class="toc"> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.allocator_introduction.allocator_properties">Properties of <span class="bold"><strong>Boost.Interprocess</strong></span> allocators</a></span></dt> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.allocator_introduction.allocator_swapping">Swapping Boost.Interprocess allocators</a></span></dt> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.allocator_introduction.allocator">allocator: A general purpose allocator for managed memory segments</a></span></dt> </dl></div> <p> As seen, <span class="bold"><strong>Boost.Interprocess</strong></span> offers raw memory allocation and object construction using managed memory segments (managed shared memory, managed mapped files...) and one of the first user requests is the use of containers in managed shared memories. To achieve this, <span class="bold"><strong>Boost.Interprocess</strong></span> makes use of managed memory segment's memory allocation algorithms to build several memory allocation schemes, including general purpose and node allocators. </p> <p> <span class="bold"><strong>Boost.Interprocess</strong></span> STL compatible allocators are configurable via template parameters. Allocators define their <code class="computeroutput"><span class="identifier">pointer</span></code> typedef based on the <code class="computeroutput"><span class="identifier">void_pointer</span></code> typedef of the segment manager passed as template argument. When this <code class="computeroutput"><span class="identifier">segment_manager</span><span class="special">::</span><span class="identifier">void_pointer</span></code> is a relative pointer, (for example, <code class="computeroutput"><span class="identifier">offset_ptr</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>) the user can place these allocators in memory mapped in different base addresses in several processes. </p> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="interprocess.allocators_containers.allocator_introduction.allocator_properties"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.allocator_introduction.allocator_properties" title="Properties of Boost.Interprocess allocators">Properties of <span class="bold"><strong>Boost.Interprocess</strong></span> allocators</a> </h4></div></div></div> <p> Container allocators are normally default-constructible because the are stateless. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span></code> and <span class="bold"><strong>Boost.Pool's</strong></span> <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">pool_allocator</span></code>/<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fast_pool_allocator</span></code> are examples of default-constructible allocators. </p> <p> On the other hand, <span class="bold"><strong>Boost.Interprocess</strong></span> allocators need to allocate memory from a concrete memory segment and not from a system-wide memory source (like the heap). <span class="bold"><strong>Boost.Interprocess</strong></span> allocators are <span class="bold"><strong>stateful</strong></span>, which means that they must be configured to tell them where the shared memory or the memory mapped file is. </p> <p> This information is transmitted at compile-time and run-time: The allocators receive a template parameter defining the type of the segment manager and their constructor receive a pointer to the segment manager of the managed memory segment where the user wants to allocate the values. </p> <p> <span class="bold"><strong>Boost.Interprocess</strong></span> allocators have <span class="bold"><strong>no default-constructors</strong></span> and containers must be explicitly initialized with a configured allocator: </p> <pre class="programlisting"><span class="comment">//The allocators must be templatized with the segment manager type</span> <span class="keyword">typedef</span> <span class="identifier">any_interprocess_allocator</span> <span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">segment_manager</span><span class="special">,</span> <span class="special">...&gt;</span> <span class="identifier">Allocator</span><span class="special">;</span> <span class="comment">//The allocator must be constructed with a pointer to the segment manager</span> <span class="identifier">Allocator</span> <span class="identifier">alloc_instance</span> <span class="special">(</span><span class="identifier">segment</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">(),</span> <span class="special">...);</span> <span class="comment">//Containers must be initialized with a configured allocator</span> <span class="keyword">typedef</span> <span class="identifier">my_list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;</span> <span class="identifier">MyIntList</span><span class="special">;</span> <span class="identifier">MyIntList</span> <span class="identifier">mylist</span><span class="special">(</span><span class="identifier">alloc_inst</span><span class="special">);</span> <span class="comment">//This would lead to a compilation error, because</span> <span class="comment">//the allocator has no default constructor</span> <span class="comment">//MyIntList mylist;</span> </pre> <p> <span class="bold"><strong>Boost.Interprocess</strong></span> allocators also have a <code class="computeroutput"><span class="identifier">get_segment_manager</span><span class="special">()</span></code> function that returns the underlying segment manager that they have received in the constructor: </p> <pre class="programlisting"><span class="identifier">Allocator</span><span class="special">::</span><span class="identifier">segment_manager</span> <span class="identifier">s</span> <span class="special">=</span> <span class="identifier">alloc_instance</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">();</span> <span class="identifier">AnotherType</span> <span class="special">*</span><span class="identifier">a</span> <span class="special">=</span> <span class="identifier">s</span><span class="special">-&gt;</span><span class="identifier">construct</span><span class="special">&lt;</span><span class="identifier">AnotherType</span><span class="special">&gt;(</span><span class="identifier">anonymous_instance</span><span class="special">)(/*</span><span class="identifier">Parameters</span><span class="special">*/);</span> </pre> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="interprocess.allocators_containers.allocator_introduction.allocator_swapping"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.allocator_introduction.allocator_swapping" title="Swapping Boost.Interprocess allocators">Swapping Boost.Interprocess allocators</a> </h4></div></div></div> <p> When swapping STL containers, there is an active discussion on what to do with the allocators. Some STL implementations, for example Dinkumware from Visual .NET 2003, perform a deep swap of the whole container through a temporary when allocators are not equal. The <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1599.html" target="_top">proposed resolution</a> to container swapping is that allocators should be swapped in a non-throwing way. </p> <p> Unfortunately, this approach is not valid with shared memory. Using heap allocators, if Group1 of node allocators share a common segregated storage, and Group2 share another common segregated storage, a simple pointer swapping is needed to swap an allocator of Group1 and another allocator of Group2. But when the user wants to swap two shared memory allocators, each one placed in a different shared memory segment, this is not possible. As generally shared memory is mapped in different addresses in each process, a pointer placed in one segment can't point to any object placed in other shared memory segment, since in each process, the distance between the segments is different. However, if both shared memory allocators are in the same segment, a non-throwing swap is possible, just like heap allocators. </p> <p> Until a final resolution is achieved. <span class="bold"><strong>Boost.Interprocess</strong></span> allocators implement a non-throwing swap function that swaps internal pointers. If an allocator placed in a shared memory segment is swapped with other placed in a different shared memory segment, the result is undefined. But a crash is quite sure. </p> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="interprocess.allocators_containers.allocator_introduction.allocator"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.allocator_introduction.allocator" title="allocator: A general purpose allocator for managed memory segments">allocator: A general purpose allocator for managed memory segments</a> </h4></div></div></div> <p> The <code class="computeroutput"><a class="link" href="../boost/interprocess/allocator.html" title="Class template allocator">allocator</a></code> class defines an allocator class that uses the managed memory segment's algorithm to allocate and deallocate memory. This is achieved through the <span class="bold"><strong>segment manager</strong></span> of the managed memory segment. This allocator is the equivalent for managed memory segments of the standard <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span></code>. <code class="computeroutput"><a class="link" href="../boost/interprocess/allocator.html" title="Class template allocator">allocator</a></code> is templatized with the allocated type, and the segment manager. </p> <p> <span class="bold"><strong>Equality:</strong></span> Two <code class="computeroutput"><a class="link" href="../boost/interprocess/allocator.html" title="Class template allocator">allocator</a></code> instances constructed with the same segment manager compare equal. If an instance is created using copy constructor, that instance compares equal with the original one. </p> <p> <span class="bold"><strong>Allocation thread-safety:</strong></span> Allocation and deallocation are implemented as calls to the segment manager's allocation function so the allocator offers the same thread-safety as the segment manager. </p> <p> To use <code class="computeroutput"><a class="link" href="../boost/interprocess/allocator.html" title="Class template allocator">allocator</a></code> you must include the following header: </p> <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">allocators</span><span class="special">/</span><span class="identifier">allocator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> </pre> <p> <code class="computeroutput"><a class="link" href="../boost/interprocess/allocator.html" title="Class template allocator">allocator</a></code> has the following declaration: </p> <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">interprocess</span> <span class="special">{</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">SegmentManager</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">allocator</span><span class="special">;</span> <span class="special">}</span> <span class="comment">//namespace interprocess {</span> <span class="special">}</span> <span class="comment">//namespace boost {</span> </pre> <p> The allocator just provides the needed typedefs and forwards all allocation and deallocation requests to the segment manager passed in the constructor, just like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span></code> forwards the requests to <code class="computeroutput"><span class="keyword">operator</span> <span class="keyword">new</span><span class="special">[]</span></code>. </p> <p> Using <code class="computeroutput"><a class="link" href="../boost/interprocess/allocator.html" title="Class template allocator">allocator</a></code> is straightforward: </p> <p> </p> <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">managed_shared_memory</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">allocators</span><span class="special">/</span><span class="identifier">allocator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">;</span> <span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span> <span class="special">{</span> <span class="comment">//Remove shared memory on construction and destruction</span> <span class="keyword">struct</span> <span class="identifier">shm_remove</span> <span class="special">{</span> <span class="identifier">shm_remove</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> <span class="special">~</span><span class="identifier">shm_remove</span><span class="special">(){</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> <span class="special">}</span> <span class="identifier">remover</span><span class="special">;</span> <span class="comment">//Create shared memory</span> <span class="identifier">managed_shared_memory</span> <span class="identifier">segment</span><span class="special">(</span><span class="identifier">create_only</span><span class="special">,</span> <span class="string">"MySharedMemory"</span><span class="special">,</span> <span class="comment">//segment name</span> <span class="number">65536</span><span class="special">);</span> <span class="comment">//Create an allocator that allocates ints from the managed segment</span> <span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">segment_manager</span><span class="special">&gt;</span> <span class="identifier">allocator_instance</span><span class="special">(</span><span class="identifier">segment</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">());</span> <span class="comment">//Copy constructed allocator is equal</span> <span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">segment_manager</span><span class="special">&gt;</span> <span class="identifier">allocator_instance2</span><span class="special">(</span><span class="identifier">allocator_instance</span><span class="special">);</span> <span class="identifier">assert</span><span class="special">(</span><span class="identifier">allocator_instance2</span> <span class="special">==</span> <span class="identifier">allocator_instance</span><span class="special">);</span> <span class="comment">//Allocate and deallocate memory for 100 ints</span> <span class="identifier">allocator_instance2</span><span class="special">.</span><span class="identifier">deallocate</span><span class="special">(</span><span class="identifier">allocator_instance</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">(</span><span class="number">100</span><span class="special">),</span> <span class="number">100</span><span class="special">);</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span> </pre> <p> </p> </div> </div> <div class="section"> <div class="titlepage"><div><div><h3 class="title"> <a name="interprocess.allocators_containers.stl_allocators_segregated_storage"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_segregated_storage" title="Segregated storage node allocators">Segregated storage node allocators</a> </h3></div></div></div> <div class="toc"><dl class="toc"> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_segregated_storage.segregated_allocators_common">Additional parameters and functions of segregated storage node allocators</a></span></dt> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_segregated_storage.node_allocator">node_allocator: A process-shared segregated storage</a></span></dt> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_segregated_storage.private_node_allocator">private_node_allocator: a private segregated storage</a></span></dt> <dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_segregated_storage.cached_node_allocator">cached_node_allocator: caching nodes to avoid overhead</a></span></dt> </dl></div> <p> Variable size memory algorithms waste some space in management information for each allocation. Sometimes, usually for small objects, this is not acceptable. Memory algorithms can also fragment the managed memory segment under some allocation and deallocation schemes, reducing their performance. When allocating many objects of the same type, a simple segregated storage becomes a fast and space-friendly allocator, as explained in the <a href="http://www.boost.org/libs/pool/" target="_top"><span class="bold"><strong>Boost.Pool</strong></span></a> library. </p> <p> Segregate storage node allocators allocate large memory chunks from a general purpose memory allocator and divide that chunk into several nodes. No bookkeeping information is stored in the nodes to achieve minimal memory waste: free nodes are linked using a pointer constructed in the memory of the node. </p> <p> <span class="bold"><strong>Boost.Interprocess</strong></span> offers 3 allocators based on this segregated storage algorithm: <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code>, <code class="computeroutput"><a class="link" href="../boost/interprocess/private_node_allocator.html" title="Class template private_node_allocator">private_node_allocator</a></code> and <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_node_allocator.html" title="Class template cached_node_allocator">cached_node_allocator</a></code>. </p> <p> To know the details of the implementation of of the segregated storage pools see the <a class="link" href="architecture.html#interprocess.architecture.allocators_containers.implementation_segregated_storage_pools" title="Implementation of Boost.Interprocess segregated storage pools">Implementation of <span class="bold"><strong>Boost.Interprocess</strong></span> segregated storage pools</a> section. </p> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="interprocess.allocators_containers.stl_allocators_segregated_storage.segregated_allocators_common"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_segregated_storage.segregated_allocators_common" title="Additional parameters and functions of segregated storage node allocators">Additional parameters and functions of segregated storage node allocators</a> </h4></div></div></div> <p> <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code>, <code class="computeroutput"><a class="link" href="../boost/interprocess/private_node_allocator.html" title="Class template private_node_allocator">private_node_allocator</a></code> and <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_node_allocator.html" title="Class template cached_node_allocator">cached_node_allocator</a></code> implement the standard allocator interface and the functions explained in the <a class="link" href="allocators_containers.html#interprocess.allocators_containers.allocator_introduction.allocator_properties" title="Properties of Boost.Interprocess allocators">Properties of Boost.Interprocess allocators</a>. </p> <p> All these allocators are templatized by 3 parameters: </p> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <li class="listitem"> <code class="computeroutput"><span class="keyword">class</span> <span class="identifier">T</span></code>: The type to be allocated. </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">class</span> <span class="identifier">SegmentManager</span></code>: The type of the segment manager that will be passed in the constructor. </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">NodesPerChunk</span></code>: The number of nodes that a memory chunk will contain. This value will define the size of the memory the pool will request to the segment manager when the pool runs out of nodes. This parameter has a default value. </li> </ul></div> <p> These allocators also offer the <code class="computeroutput"><span class="identifier">deallocate_free_chunks</span><span class="special">()</span></code> function. This function will traverse all the memory chunks of the pool and will return to the managed memory segment the free chunks of memory. If this function is not used, deallocating the free chunks does not happen until the pool is destroyed so the only way to return memory allocated by the pool to the segment before destructing the pool is calling manually this function. This function is quite time-consuming because it has quadratic complexity (O(N^2)). </p> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="interprocess.allocators_containers.stl_allocators_segregated_storage.node_allocator"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_segregated_storage.node_allocator" title="node_allocator: A process-shared segregated storage">node_allocator: A process-shared segregated storage</a> </h4></div></div></div> <p> For heap-memory node allocators (like <span class="bold"><strong>Boost.Pool's</strong></span> <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fast_pool_allocator</span></code> usually a global, thread-shared singleton pool is used for each node size. This is not possible if you try to share a node allocator between processes. To achieve this sharing <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code> uses the segment manager's unique type allocation service (see <a class="link" href="managed_memory_segments.html#interprocess.managed_memory_segments.managed_memory_segment_features.unique" title="Unique instance construction">Unique instance construction</a> section). </p> <p> In the initialization, a <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code> object searches this unique object in the segment. If it is not preset, it builds one. This way, all <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code> objects built inside a memory segment share a unique memory pool. </p> <p> The common segregated storage is not only shared between node_allocators of the same type, but it is also shared between all node allocators that allocate objects of the same size, for example, <span class="bold"><strong>node_allocator&lt;uint32&gt;</strong></span> and <span class="bold"><strong>node_allocator&lt;float32&gt;</strong></span>. This saves a lot of memory but also imposes an synchronization overhead for each node allocation. </p> <p> The dynamically created common segregated storage integrates a reference count so that a <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code> can know if any other <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code> is attached to the same common segregated storage. When the last allocator attached to the pool is destroyed, the pool is destroyed. </p> <p> <span class="bold"><strong>Equality:</strong></span> Two <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code> instances constructed with the same segment manager compare equal. If an instance is created using copy constructor, that instance compares equal with the original one. </p> <p> <span class="bold"><strong>Allocation thread-safety:</strong></span> Allocation and deallocation are implemented as calls to the shared pool. The shared pool offers the same synchronization guarantees as the segment manager. </p> <p> To use <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code>, you must include the following header: </p> <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">allocators</span><span class="special">/</span><span class="identifier">node_allocator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> </pre> <p> <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code> has the following declaration: </p> <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">interprocess</span> <span class="special">{</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">SegmentManager</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">NodesPerChunk</span> <span class="special">=</span> <span class="special">...&gt;</span> <span class="keyword">class</span> <span class="identifier">node_allocator</span><span class="special">;</span> <span class="special">}</span> <span class="comment">//namespace interprocess {</span> <span class="special">}</span> <span class="comment">//namespace boost {</span> </pre> <p> An example using <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code>: </p> <p> </p> <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">managed_shared_memory</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">allocators</span><span class="special">/</span><span class="identifier">node_allocator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">;</span> <span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span> <span class="special">{</span> <span class="comment">//Remove shared memory on construction and destruction</span> <span class="keyword">struct</span> <span class="identifier">shm_remove</span> <span class="special">{</span> <span class="identifier">shm_remove</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> <span class="special">~</span><span class="identifier">shm_remove</span><span class="special">(){</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> <span class="special">}</span> <span class="identifier">remover</span><span class="special">;</span> <span class="comment">//Create shared memory</span> <span class="identifier">managed_shared_memory</span> <span class="identifier">segment</span><span class="special">(</span><span class="identifier">create_only</span><span class="special">,</span> <span class="string">"MySharedMemory"</span><span class="special">,</span> <span class="comment">//segment name</span> <span class="number">65536</span><span class="special">);</span> <span class="comment">//Create a node_allocator that allocates ints from the managed segment</span> <span class="comment">//The number of chunks per segment is the default value</span> <span class="keyword">typedef</span> <span class="identifier">node_allocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">segment_manager</span><span class="special">&gt;</span> <span class="identifier">node_allocator_t</span><span class="special">;</span> <span class="identifier">node_allocator_t</span> <span class="identifier">allocator_instance</span><span class="special">(</span><span class="identifier">segment</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">());</span> <span class="comment">//Create another node_allocator. Since the segment manager address</span> <span class="comment">//is the same, this node_allocator will be</span> <span class="comment">//attached to the same pool so "allocator_instance2" can deallocate</span> <span class="comment">//nodes allocated by "allocator_instance"</span> <span class="identifier">node_allocator_t</span> <span class="identifier">allocator_instance2</span><span class="special">(</span><span class="identifier">segment</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">());</span> <span class="comment">//Create another node_allocator using copy-constructor. This</span> <span class="comment">//node_allocator will also be attached to the same pool</span> <span class="identifier">node_allocator_t</span> <span class="identifier">allocator_instance3</span><span class="special">(</span><span class="identifier">allocator_instance2</span><span class="special">);</span> <span class="comment">//All allocators are equal</span> <span class="identifier">assert</span><span class="special">(</span><span class="identifier">allocator_instance</span> <span class="special">==</span> <span class="identifier">allocator_instance2</span><span class="special">);</span> <span class="identifier">assert</span><span class="special">(</span><span class="identifier">allocator_instance2</span> <span class="special">==</span> <span class="identifier">allocator_instance3</span><span class="special">);</span> <span class="comment">//So memory allocated with one can be deallocated with another</span> <span class="identifier">allocator_instance2</span><span class="special">.</span><span class="identifier">deallocate</span><span class="special">(</span><span class="identifier">allocator_instance</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">(</span><span class="number">1</span><span class="special">),</span> <span class="number">1</span><span class="special">);</span> <span class="identifier">allocator_instance3</span><span class="special">.</span><span class="identifier">deallocate</span><span class="special">(</span><span class="identifier">allocator_instance2</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">(</span><span class="number">1</span><span class="special">),</span> <span class="number">1</span><span class="special">);</span> <span class="comment">//The common pool will be destroyed here, since no allocator is</span> <span class="comment">//attached to the pool</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span> </pre> <p> </p> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="interprocess.allocators_containers.stl_allocators_segregated_storage.private_node_allocator"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_segregated_storage.private_node_allocator" title="private_node_allocator: a private segregated storage">private_node_allocator: a private segregated storage</a> </h4></div></div></div> <p> As said, the node_allocator shares a common segregated storage between node_allocators that allocate objects of the same size and this optimizes memory usage. However, it needs a unique/named object construction feature so that this sharing can be possible. Also imposes a synchronization overhead per node allocation because of this share. Sometimes, the unique object service is not available (for example, when building index types to implement the named allocation service itself) or the synchronization overhead is not acceptable. Many times the programmer wants to make sure that the pool is destroyed when the allocator is destroyed, to free the memory as soon as possible. </p> <p> So <span class="bold"><strong>private_node_allocator</strong></span> uses the same segregated storage as <code class="computeroutput"><span class="identifier">node_allocator</span></code>, but each <span class="bold"><strong>private_node_allocator</strong></span> has its own segregated storage pool. No synchronization is used when allocating nodes, so there is far less overhead for an operation that usually involves just a few pointer operations when allocating and deallocating a node. </p> <p> <span class="bold"><strong>Equality:</strong></span> Two <code class="computeroutput"><a class="link" href="../boost/interprocess/private_node_allocator.html" title="Class template private_node_allocator">private_node_allocator</a></code> instances <span class="bold"><strong>never</strong></span> compare equal. Memory allocated with one allocator <span class="bold"><strong>can't</strong></span> be deallocated with another one. </p> <p> <span class="bold"><strong>Allocation thread-safety:</strong></span> Allocation and deallocation are <span class="bold"><strong>not</strong></span> thread-safe. </p> <p> To use <code class="computeroutput"><a class="link" href="../boost/interprocess/private_node_allocator.html" title="Class template private_node_allocator">private_node_allocator</a></code>, you must include the following header: </p> <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">allocators</span><span class="special">/</span><span class="identifier">private_node_allocator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> </pre> <p> <code class="computeroutput"><a class="link" href="../boost/interprocess/private_node_allocator.html" title="Class template private_node_allocator">private_node_allocator</a></code> has the following declaration: </p> <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">interprocess</span> <span class="special">{</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">SegmentManager</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">NodesPerChunk</span> <span class="special">=</span> <span class="special">...&gt;</span> <span class="keyword">class</span> <span class="identifier">private_node_allocator</span><span class="special">;</span> <span class="special">}</span> <span class="comment">//namespace interprocess {</span> <span class="special">}</span> <span class="comment">//namespace boost {</span> </pre> <p> An example using <code class="computeroutput"><a class="link" href="../boost/interprocess/private_node_allocator.html" title="Class template private_node_allocator">private_node_allocator</a></code>: </p> <p> </p> <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">managed_shared_memory</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">allocators</span><span class="special">/</span><span class="identifier">private_node_allocator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">;</span> <span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span> <span class="special">{</span> <span class="comment">//Remove shared memory on construction and destruction</span> <span class="keyword">struct</span> <span class="identifier">shm_remove</span> <span class="special">{</span> <span class="identifier">shm_remove</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> <span class="special">~</span><span class="identifier">shm_remove</span><span class="special">(){</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> <span class="special">}</span> <span class="identifier">remover</span><span class="special">;</span> <span class="comment">//Create shared memory</span> <span class="identifier">managed_shared_memory</span> <span class="identifier">segment</span><span class="special">(</span><span class="identifier">create_only</span><span class="special">,</span> <span class="string">"MySharedMemory"</span><span class="special">,</span> <span class="comment">//segment name</span> <span class="number">65536</span><span class="special"