1887 lines
197 KiB
HTML
1887 lines
197 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
<html>
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
<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.79.1">
|
||
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
|
||
<link rel="up" href="../interprocess.html" title="Chapter 18. 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"><</span><span class="keyword">void</span><span class="special">></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"><</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">...></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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">></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">-></span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">AnotherType</span><span class="special">>(</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"><</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">></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"><</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="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"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></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"><</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="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"><</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="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<uint32></strong></span>
|
||
and <span class="bold"><strong>node_allocator<float32></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"><</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">></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"><</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">...></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"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></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"><</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="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"><</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">></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"><</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">...></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"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></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 private_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">private_node_allocator</span><span class="special"><</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="identifier">private_node_allocator_t</span><span class="special">;</span>
|
||
<span class="identifier">private_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 private_node_allocator.</span>
|
||
<span class="identifier">private_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">//Although the segment manager address</span>
|
||
<span class="comment">//is the same, this private_node_allocator will have its own pool so</span>
|
||
<span class="comment">//"allocator_instance2" CAN'T deallocate nodes allocated by "allocator_instance".</span>
|
||
<span class="comment">//"allocator_instance2" is NOT equal to "allocator_instance"</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="comment">//Create another node_allocator using copy-constructor.</span>
|
||
<span class="identifier">private_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">//This allocator is also unequal to allocator_instance2</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">//Pools are destroyed with the allocators</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.cached_node_allocator"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_segregated_storage.cached_node_allocator" title="cached_node_allocator: caching nodes to avoid overhead">cached_node_allocator:
|
||
caching nodes to avoid overhead</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
The total node sharing of <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code>
|
||
can impose a high overhead for some applications and the minimal synchronization
|
||
overhead of <code class="computeroutput"><a class="link" href="../boost/interprocess/private_node_allocator.html" title="Class template private_node_allocator">private_node_allocator</a></code>
|
||
can impose a unacceptable memory waste for other applications.
|
||
</p>
|
||
<p>
|
||
To solve this, <span class="bold"><strong>Boost.Interprocess</strong></span> offers
|
||
an allocator, <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_node_allocator.html" title="Class template cached_node_allocator">cached_node_allocator</a></code>,
|
||
that allocates nodes from the common pool but caches some of them privately
|
||
so that following allocations have no synchronization overhead. When the
|
||
cache is full, the allocator returns some cached nodes to the common pool,
|
||
and those will be available to other allocators.
|
||
</p>
|
||
<p>
|
||
<span class="bold"><strong>Equality:</strong></span> Two <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_node_allocator.html" title="Class template cached_node_allocator">cached_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 <span class="bold"><strong>not</strong></span> thread-safe.
|
||
</p>
|
||
<p>
|
||
To use <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_node_allocator.html" title="Class template cached_node_allocator">cached_node_allocator</a></code>,
|
||
you must include the following header:
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">cached_node_allocator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
</pre>
|
||
<p>
|
||
<code class="computeroutput"><a class="link" href="../boost/interprocess/cached_node_allocator.html" title="Class template cached_node_allocator">cached_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"><</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">...></span>
|
||
<span class="keyword">class</span> <span class="identifier">cached_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>
|
||
A <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_node_allocator.html" title="Class template cached_node_allocator">cached_node_allocator</a></code>
|
||
instance and a <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code>
|
||
instance share the same pool if both instances receive the same template
|
||
parameters. This means that nodes returned to the shared pool by one of
|
||
them can be reused by the other. Please note that this does not mean that
|
||
both allocators compare equal, this is just information for programmers
|
||
that want to maximize the use of the pool.
|
||
</p>
|
||
<p>
|
||
<code class="computeroutput"><a class="link" href="../boost/interprocess/cached_node_allocator.html" title="Class template cached_node_allocator">cached_node_allocator</a></code>,
|
||
offers additional functions to control the cache (the cache can be controlled
|
||
per instance):
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||
<li class="listitem">
|
||
<code class="computeroutput"><span class="keyword">void</span> <span class="identifier">set_max_cached_nodes</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span>
|
||
<span class="identifier">n</span><span class="special">)</span></code>:
|
||
Sets the maximum cached nodes limit. If cached nodes reach the limit,
|
||
some are returned to the shared pool.
|
||
</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">get_max_cached_nodes</span><span class="special">()</span> <span class="keyword">const</span></code>:
|
||
Returns the maximum cached nodes limit.
|
||
</li>
|
||
<li class="listitem">
|
||
<code class="computeroutput"><span class="keyword">void</span> <span class="identifier">deallocate_cache</span><span class="special">()</span></code>: Returns the cached nodes to the
|
||
shared pool.
|
||
</li>
|
||
</ul></div>
|
||
<p>
|
||
An example using <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>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">cached_node_allocator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></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 cached_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">cached_node_allocator</span><span class="special"><</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="identifier">cached_node_allocator_t</span><span class="special">;</span>
|
||
<span class="identifier">cached_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">//The max cached nodes are configurable per instance</span>
|
||
<span class="identifier">allocator_instance</span><span class="special">.</span><span class="identifier">set_max_cached_nodes</span><span class="special">(</span><span class="number">3</span><span class="special">);</span>
|
||
|
||
<span class="comment">//Create another cached_node_allocator. Since the segment manager address</span>
|
||
<span class="comment">//is the same, this cached_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">cached_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">//The max cached nodes are configurable per instance</span>
|
||
<span class="identifier">allocator_instance2</span><span class="special">.</span><span class="identifier">set_max_cached_nodes</span><span class="special">(</span><span class="number">5</span><span class="special">);</span>
|
||
|
||
<span class="comment">//Create another cached_node_allocator using copy-constructor. This</span>
|
||
<span class="comment">//cached_node_allocator will also be attached to the same pool</span>
|
||
<span class="identifier">cached_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">//We can clear the cache</span>
|
||
<span class="identifier">allocator_instance3</span><span class="special">.</span><span class="identifier">deallocate_cache</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>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="interprocess.allocators_containers.stl_allocators_adaptive"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_adaptive" title="Adaptive pool node allocators">Adaptive
|
||
pool 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_adaptive.adaptive_allocators_common">Additional
|
||
parameters and functions of adaptive pool node allocators</a></span></dt>
|
||
<dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_adaptive.adaptive_pool">adaptive_pool:
|
||
a process-shared adaptive pool</a></span></dt>
|
||
<dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_adaptive.private_adaptive_pool">private_adaptive_pool:
|
||
a private adaptive pool</a></span></dt>
|
||
<dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_adaptive.cached_adaptive_pool">cached_adaptive_pool:
|
||
Avoiding synchronization overhead</a></span></dt>
|
||
</dl></div>
|
||
<p>
|
||
Node allocators based on simple segregated storage algorithm are both space-efficient
|
||
and fast but they have a problem: they only can grow. Every allocated node
|
||
avoids any payload to store additional data and that leads to the following
|
||
limitation: when a node is deallocated, it's stored in a free list of nodes
|
||
but memory is not returned to the segment manager so a deallocated node can
|
||
be only reused by other containers using the same node pool.
|
||
</p>
|
||
<p>
|
||
This behaviour can be problematic if several containers use <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">boost::interprocess::node_allocator</a></code>
|
||
to temporarily allocate a lot of objects but they end storing a few of them:
|
||
the node pool will be full of nodes that won't be reused wasting memory from
|
||
the segment.
|
||
</p>
|
||
<p>
|
||
Adaptive pool based allocators trade some space (the overhead can be as low
|
||
as 1%) and performance (acceptable for many applications) with the ability
|
||
to return free chunks of nodes to the memory segment, so that they can be
|
||
used by any other container or managed object construction. To know the details
|
||
of the implementation of of "adaptive pools" see the <a class="link" href="architecture.html#interprocess.architecture.allocators_containers.implementation_adaptive_pools" title="Implementation of Boost.Interprocess adaptive pools">Implementation
|
||
of <span class="bold"><strong>Boost.Intrusive</strong></span> adaptive pools</a>
|
||
section.
|
||
</p>
|
||
<p>
|
||
Like with segregated storage based node allocators, Boost.Interprocess offers
|
||
3 new allocators: <code class="computeroutput"><a class="link" href="../boost/interprocess/adaptive_pool.html" title="Class template adaptive_pool">adaptive_pool</a></code>,
|
||
<code class="computeroutput"><a class="link" href="../boost/interprocess/private_adaptive_pool.html" title="Class template private_adaptive_pool">private_adaptive_pool</a></code>,
|
||
<code class="computeroutput"><a class="link" href="../boost/interprocess/cached_adaptive_pool.html" title="Class template cached_adaptive_pool">cached_adaptive_pool</a></code>.
|
||
</p>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="interprocess.allocators_containers.stl_allocators_adaptive.adaptive_allocators_common"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_adaptive.adaptive_allocators_common" title="Additional parameters and functions of adaptive pool node allocators">Additional
|
||
parameters and functions of adaptive pool node allocators</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
<code class="computeroutput"><a class="link" href="../boost/interprocess/adaptive_pool.html" title="Class template adaptive_pool">adaptive_pool</a></code>,
|
||
<code class="computeroutput"><a class="link" href="../boost/interprocess/private_adaptive_pool.html" title="Class template private_adaptive_pool">private_adaptive_pool</a></code>
|
||
and <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_adaptive_pool.html" title="Class template cached_adaptive_pool">cached_adaptive_pool</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 4 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>
|
||
<li class="listitem">
|
||
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">MaxFreeChunks</span></code>:
|
||
The maximum number of free chunks that the pool will hold. If this
|
||
limit is reached the pool returns the chunks to the segment manager.
|
||
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. This function is much faster than for
|
||
segregated storage allocators, because the adaptive pool algorithm offers
|
||
constant-time access to free chunks.
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="interprocess.allocators_containers.stl_allocators_adaptive.adaptive_pool"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_adaptive.adaptive_pool" title="adaptive_pool: a process-shared adaptive pool">adaptive_pool:
|
||
a process-shared adaptive pool</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
Just like <code class="computeroutput"><a class="link" href="../boost/interprocess/node_allocator.html" title="Class template node_allocator">node_allocator</a></code>
|
||
a global, process-thread pool is used for each node size. In the initialization,
|
||
<code class="computeroutput"><a class="link" href="../boost/interprocess/adaptive_pool.html" title="Class template adaptive_pool">adaptive_pool</a></code>
|
||
searches the pool in the segment. If it is not preset, it builds one. The
|
||
adaptive pool, is created using a unique name. The adaptive pool it is
|
||
also shared between all node_allocators that allocate objects of the same
|
||
size, for example, <span class="bold"><strong>adaptive_pool<uint32></strong></span>
|
||
and <span class="bold"><strong>adaptive_pool<float32></strong></span>.
|
||
</p>
|
||
<p>
|
||
The common adaptive pool is destroyed when all the allocators attached
|
||
to the pool are destroyed.
|
||
</p>
|
||
<p>
|
||
<span class="bold"><strong>Equality:</strong></span> Two <code class="computeroutput"><a class="link" href="../boost/interprocess/adaptive_pool.html" title="Class template adaptive_pool">adaptive_pool</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/adaptive_pool.html" title="Class template adaptive_pool">adaptive_pool</a></code>,
|
||
you must include the following header:
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">adaptive_pool</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
</pre>
|
||
<p>
|
||
<code class="computeroutput"><a class="link" href="../boost/interprocess/adaptive_pool.html" title="Class template adaptive_pool">adaptive_pool</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"><</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">...,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">MaxFreeChunks</span> <span class="special">=</span> <span class="special">...></span>
|
||
<span class="keyword">class</span> <span class="identifier">adaptive_pool</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/adaptive_pool.html" title="Class template adaptive_pool">adaptive_pool</a></code>:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">adaptive_pool</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></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 adaptive_pool 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">adaptive_pool</span><span class="special"><</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="identifier">adaptive_pool_t</span><span class="special">;</span>
|
||
<span class="identifier">adaptive_pool_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 adaptive_pool. Since the segment manager address</span>
|
||
<span class="comment">//is the same, this adaptive_pool 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">adaptive_pool_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 adaptive_pool using copy-constructor. This</span>
|
||
<span class="comment">//adaptive_pool will also be attached to the same pool</span>
|
||
<span class="identifier">adaptive_pool_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_adaptive.private_adaptive_pool"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_adaptive.private_adaptive_pool" title="private_adaptive_pool: a private adaptive pool">private_adaptive_pool:
|
||
a private adaptive pool</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
Just like <code class="computeroutput"><a class="link" href="../boost/interprocess/private_node_allocator.html" title="Class template private_node_allocator">private_node_allocator</a></code>
|
||
owns a private segregated storage pool, <code class="computeroutput"><a class="link" href="../boost/interprocess/private_adaptive_pool.html" title="Class template private_adaptive_pool">private_adaptive_pool</a></code>
|
||
owns its own adaptive pool. If the user wants to avoid the excessive node
|
||
allocation synchronization overhead in a container <code class="computeroutput"><a class="link" href="../boost/interprocess/private_adaptive_pool.html" title="Class template private_adaptive_pool">private_adaptive_pool</a></code>
|
||
is a good choice.
|
||
</p>
|
||
<p>
|
||
<span class="bold"><strong>Equality:</strong></span> Two <code class="computeroutput"><a class="link" href="../boost/interprocess/private_adaptive_pool.html" title="Class template private_adaptive_pool">private_adaptive_pool</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_adaptive_pool.html" title="Class template private_adaptive_pool">private_adaptive_pool</a></code>,
|
||
you must include the following header:
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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_adaptive_pool</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
</pre>
|
||
<p>
|
||
<code class="computeroutput"><a class="link" href="../boost/interprocess/private_adaptive_pool.html" title="Class template private_adaptive_pool">private_adaptive_pool</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"><</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">...,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">MaxFreeChunks</span> <span class="special">=</span> <span class="special">...></span>
|
||
<span class="keyword">class</span> <span class="identifier">private_adaptive_pool</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_adaptive_pool.html" title="Class template private_adaptive_pool">private_adaptive_pool</a></code>:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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_adaptive_pool</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></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 private_adaptive_pool 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">private_adaptive_pool</span><span class="special"><</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="identifier">private_adaptive_pool_t</span><span class="special">;</span>
|
||
<span class="identifier">private_adaptive_pool_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 private_adaptive_pool.</span>
|
||
<span class="identifier">private_adaptive_pool_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">//Although the segment manager address</span>
|
||
<span class="comment">//is the same, this private_adaptive_pool will have its own pool so</span>
|
||
<span class="comment">//"allocator_instance2" CAN'T deallocate nodes allocated by "allocator_instance".</span>
|
||
<span class="comment">//"allocator_instance2" is NOT equal to "allocator_instance"</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="comment">//Create another adaptive_pool using copy-constructor.</span>
|
||
<span class="identifier">private_adaptive_pool_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">//This allocator is also unequal to allocator_instance2</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">//Pools are destroyed with the allocators</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_adaptive.cached_adaptive_pool"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.stl_allocators_adaptive.cached_adaptive_pool" title="cached_adaptive_pool: Avoiding synchronization overhead">cached_adaptive_pool:
|
||
Avoiding synchronization overhead</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
Adaptive pools have also a cached version. In this allocator the allocator
|
||
caches some nodes to avoid the synchronization and bookkeeping overhead
|
||
of the shared adaptive pool. <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_adaptive_pool.html" title="Class template cached_adaptive_pool">cached_adaptive_pool</a></code>
|
||
allocates nodes from the common adaptive pool but caches some of them privately
|
||
so that following allocations have no synchronization overhead. When the
|
||
cache is full, the allocator returns some cached nodes to the common pool,
|
||
and those will be available to other <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_adaptive_pool.html" title="Class template cached_adaptive_pool">cached_adaptive_pools</a></code>
|
||
or <code class="computeroutput"><a class="link" href="../boost/interprocess/adaptive_pool.html" title="Class template adaptive_pool">adaptive_pools</a></code>
|
||
of the same managed segment.
|
||
</p>
|
||
<p>
|
||
<span class="bold"><strong>Equality:</strong></span> Two <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_adaptive_pool.html" title="Class template cached_adaptive_pool">cached_adaptive_pool</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 <span class="bold"><strong>not</strong></span> thread-safe.
|
||
</p>
|
||
<p>
|
||
To use <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_adaptive_pool.html" title="Class template cached_adaptive_pool">cached_adaptive_pool</a></code>,
|
||
you must include the following header:
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">cached_adaptive_pool</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
</pre>
|
||
<p>
|
||
<code class="computeroutput"><a class="link" href="../boost/interprocess/cached_adaptive_pool.html" title="Class template cached_adaptive_pool">cached_adaptive_pool</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"><</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">...,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">MaxFreeNodes</span> <span class="special">=</span> <span class="special">...></span>
|
||
<span class="keyword">class</span> <span class="identifier">cached_adaptive_pool</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>
|
||
A <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_adaptive_pool.html" title="Class template cached_adaptive_pool">cached_adaptive_pool</a></code>
|
||
instance and an <code class="computeroutput"><a class="link" href="../boost/interprocess/adaptive_pool.html" title="Class template adaptive_pool">adaptive_pool</a></code>
|
||
instance share the same pool if both instances receive the same template
|
||
parameters. This means that nodes returned to the shared pool by one of
|
||
them can be reused by the other. Please note that this does not mean that
|
||
both allocators compare equal, this is just information for programmers
|
||
that want to maximize the use of the pool.
|
||
</p>
|
||
<p>
|
||
<code class="computeroutput"><a class="link" href="../boost/interprocess/cached_adaptive_pool.html" title="Class template cached_adaptive_pool">cached_adaptive_pool</a></code>,
|
||
offers additional functions to control the cache (the cache can be controlled
|
||
per instance):
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||
<li class="listitem">
|
||
<code class="computeroutput"><span class="keyword">void</span> <span class="identifier">set_max_cached_nodes</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span>
|
||
<span class="identifier">n</span><span class="special">)</span></code>:
|
||
Sets the maximum cached nodes limit. If cached nodes reach the limit,
|
||
some are returned to the shared pool.
|
||
</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">get_max_cached_nodes</span><span class="special">()</span> <span class="keyword">const</span></code>:
|
||
Returns the maximum cached nodes limit.
|
||
</li>
|
||
<li class="listitem">
|
||
<code class="computeroutput"><span class="keyword">void</span> <span class="identifier">deallocate_cache</span><span class="special">()</span></code>: Returns the cached nodes to the
|
||
shared pool.
|
||
</li>
|
||
</ul></div>
|
||
<p>
|
||
An example using <code class="computeroutput"><a class="link" href="../boost/interprocess/cached_adaptive_pool.html" title="Class template cached_adaptive_pool">cached_adaptive_pool</a></code>:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">cached_adaptive_pool</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></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 cached_adaptive_pool 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">cached_adaptive_pool</span><span class="special"><</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="identifier">cached_adaptive_pool_t</span><span class="special">;</span>
|
||
<span class="identifier">cached_adaptive_pool_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">//The max cached nodes are configurable per instance</span>
|
||
<span class="identifier">allocator_instance</span><span class="special">.</span><span class="identifier">set_max_cached_nodes</span><span class="special">(</span><span class="number">3</span><span class="special">);</span>
|
||
|
||
<span class="comment">//Create another cached_adaptive_pool. Since the segment manager address</span>
|
||
<span class="comment">//is the same, this cached_adaptive_pool 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">cached_adaptive_pool_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">//The max cached nodes are configurable per instance</span>
|
||
<span class="identifier">allocator_instance2</span><span class="special">.</span><span class="identifier">set_max_cached_nodes</span><span class="special">(</span><span class="number">5</span><span class="special">);</span>
|
||
|
||
<span class="comment">//Create another cached_adaptive_pool using copy-constructor. This</span>
|
||
<span class="comment">//cached_adaptive_pool will also be attached to the same pool</span>
|
||
<span class="identifier">cached_adaptive_pool_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">//We can clear the cache</span>
|
||
<span class="identifier">allocator_instance3</span><span class="special">.</span><span class="identifier">deallocate_cache</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>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="interprocess.allocators_containers.containers_explained"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.containers_explained" title="Interprocess and containers in managed memory segments">Interprocess
|
||
and containers in managed memory segments</a>
|
||
</h3></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.containers_explained.stl_container_requirements">Container
|
||
requirements for Boost.Interprocess allocators</a></span></dt>
|
||
<dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.containers_explained.containers">STL
|
||
containers in managed memory segments</a></span></dt>
|
||
<dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.containers_explained.where_allocate">Where
|
||
is this being allocated?</a></span></dt>
|
||
<dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.containers_explained.containers_and_move">Move
|
||
semantics in Interprocess containers</a></span></dt>
|
||
<dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.containers_explained.containers_of_containers">Containers
|
||
of containers</a></span></dt>
|
||
</dl></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="interprocess.allocators_containers.containers_explained.stl_container_requirements"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.containers_explained.stl_container_requirements" title="Container requirements for Boost.Interprocess allocators">Container
|
||
requirements for Boost.Interprocess allocators</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
<span class="bold"><strong>Boost.Interprocess</strong></span> STL compatible allocators
|
||
offer a STL compatible allocator interface and if they define their internal
|
||
<span class="bold"><strong>pointer</strong></span> typedef as a relative pointer,
|
||
they can be used to place STL containers in shared memory, memory mapped
|
||
files or in a user defined memory segment.
|
||
</p>
|
||
<p>
|
||
However, as Scott Meyers mentions in his Effective STL book, Item 10,
|
||
<span class="emphasis"><em>"Be aware of allocator conventions and restrictions"</em></span>:
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||
<li class="listitem">
|
||
<span class="emphasis"><em>"the Standard explicitly allows library implementers
|
||
to assume that every allocator's pointer typedef is a synonym for T*"</em></span>
|
||
</li>
|
||
<li class="listitem">
|
||
<span class="emphasis"><em>"the Standard says that an implementation of the STL
|
||
is permitted to assume that all allocator objects of the same type
|
||
are equivalent and always compare equal"</em></span>
|
||
</li>
|
||
</ul></div>
|
||
<p>
|
||
Obviously, if any STL implementation ignores pointer typedefs, no smart
|
||
pointer can be used as allocator::pointer. If STL implementations assume
|
||
all allocator objects of the same type compare equal, it will assume that
|
||
two allocators, each one allocating from a different memory pool are equal,
|
||
which is a complete disaster.
|
||
</p>
|
||
<p>
|
||
STL containers that we want to place in shared memory or memory mapped
|
||
files with <span class="bold"><strong>Boost.Interprocess</strong></span> can't make
|
||
any of these assumptions, so:
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||
<li class="listitem">
|
||
STL containers may not assume that memory allocated with an allocator
|
||
can be deallocated with other allocators of the same type. All allocators
|
||
objects must compare equal only if memory allocated with one object
|
||
can be deallocated with the other one, and this can only tested with
|
||
operator==() at run-time.
|
||
</li>
|
||
<li class="listitem">
|
||
Containers' internal pointers should be of the type allocator::pointer
|
||
and containers may not assume allocator::pointer is a raw pointer.
|
||
</li>
|
||
<li class="listitem">
|
||
All objects must be constructed-destroyed via allocator::construct
|
||
and allocator::destroy functions.
|
||
</li>
|
||
</ul></div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="interprocess.allocators_containers.containers_explained.containers"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.containers_explained.containers" title="STL containers in managed memory segments">STL
|
||
containers in managed memory segments</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
Unfortunately, many STL implementations use raw pointers for internal data
|
||
and ignore allocator pointer typedefs and others suppose at some point
|
||
that the allocator::typedef is T*. This is because in practice, there wasn't
|
||
need of allocators with a pointer typedef different from T* for pooled/node
|
||
memory allocators.
|
||
</p>
|
||
<p>
|
||
Until STL implementations handle allocator::pointer typedefs in a generic
|
||
way, <span class="bold"><strong>Boost.Interprocess</strong></span> offers the following
|
||
classes:
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<span class="bold"><strong>boost:interprocess::vector</strong></span> is the
|
||
implementation of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>
|
||
ready to be used in managed memory segments like shared memory. To
|
||
use it include:
|
||
</li></ul></div>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
</pre>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<span class="bold"><strong>boost:interprocess::deque</strong></span> is the implementation
|
||
of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span></code> ready to be used in managed
|
||
memory segments like shared memory. To use it include:
|
||
</li></ul></div>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">deque</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
</pre>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<code class="computeroutput">list</code> is the
|
||
implementation of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span></code>
|
||
ready to be used in managed memory segments like shared memory. To
|
||
use it include:
|
||
</li></ul></div>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
</pre>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<code class="computeroutput">slist</code> is the
|
||
implementation of SGI's <code class="computeroutput"><span class="identifier">slist</span></code>
|
||
container (singly linked list) ready to be used in managed memory segments
|
||
like shared memory. To use it include:
|
||
</li></ul></div>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">slist</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
</pre>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<code class="computeroutput">set</code>/ <code class="computeroutput">multiset</code>/ <code class="computeroutput">map</code>/ <code class="computeroutput">multimap</code>
|
||
family is the implementation of std::set/multiset/map/multimap family
|
||
ready to be used in managed memory segments like shared memory. To
|
||
use them include:
|
||
</li></ul></div>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">set</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">map</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
</pre>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<code class="computeroutput">flat_set</code>/
|
||
<code class="computeroutput">flat_multiset</code>/
|
||
<code class="computeroutput">flat_map</code>/
|
||
<code class="computeroutput">flat_multimap</code>
|
||
classes are the adaptation and extension of Andrei Alexandrescu's famous
|
||
AssocVector class from Loki library, ready for the shared memory. These
|
||
classes offer the same functionality as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">set</span><span class="special">/</span><span class="identifier">multiset</span><span class="special">/</span><span class="identifier">map</span><span class="special">/</span><span class="identifier">multimap</span></code>
|
||
implemented with an ordered vector, which has faster lookups than the
|
||
standard ordered associative containers based on red-black trees, but
|
||
slower insertions. To use it include:
|
||
</li></ul></div>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">flat_set</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">flat_map</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
</pre>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<code class="computeroutput">basic_string</code>
|
||
is the implementation of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span></code>
|
||
ready to be used in managed memory segments like shared memory. It's
|
||
implemented using a vector-like contiguous storage, so it has fast
|
||
c string conversion and can be used with the <a class="link" href="streams.html#interprocess.streams.vectorstream" title="Formatting directly in your character vector: vectorstream">vectorstream</a>
|
||
iostream formatting classes. To use it include:
|
||
</li></ul></div>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">string</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
</pre>
|
||
<p>
|
||
All these containers have the same default arguments as standard containers
|
||
and they can be used with other, non <span class="bold"><strong>Boost.Interprocess</strong></span>
|
||
allocators (std::allocator, or boost::pool_allocator, for example).
|
||
</p>
|
||
<p>
|
||
To place any of these containers in managed memory segments, we must define
|
||
the allocator template parameter with a <span class="bold"><strong>Boost.Interprocess</strong></span>
|
||
allocator so that the container allocates the values in the managed memory
|
||
segment. To place the container itself in shared memory, we construct it
|
||
in the managed memory segment just like any other object with <span class="bold"><strong>Boost.Interprocess</strong></span>:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
|
||
<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
|
||
<span class="special">{</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="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">//A managed shared memory where we can construct objects</span>
|
||
<span class="comment">//associated with a c-string</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">//Alias an STL-like allocator of ints that allocates ints from the segment</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</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="identifier">ShmemAllocator</span><span class="special">;</span>
|
||
|
||
<span class="comment">//Alias a vector that uses the previous STL-like allocator</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">ShmemAllocator</span><span class="special">></span> <span class="identifier">MyVector</span><span class="special">;</span>
|
||
|
||
<span class="keyword">int</span> <span class="identifier">initVal</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">6</span> <span class="special">};</span>
|
||
<span class="keyword">const</span> <span class="keyword">int</span> <span class="special">*</span><span class="identifier">begVal</span> <span class="special">=</span> <span class="identifier">initVal</span><span class="special">;</span>
|
||
<span class="keyword">const</span> <span class="keyword">int</span> <span class="special">*</span><span class="identifier">endVal</span> <span class="special">=</span> <span class="identifier">initVal</span> <span class="special">+</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">initVal</span><span class="special">)/</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">initVal</span><span class="special">[</span><span class="number">0</span><span class="special">]);</span>
|
||
|
||
<span class="comment">//Initialize the STL-like allocator</span>
|
||
<span class="keyword">const</span> <span class="identifier">ShmemAllocator</span> <span class="identifier">alloc_inst</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">//Construct the vector in the shared memory segment with the STL-like allocator</span>
|
||
<span class="comment">//from a range of iterators</span>
|
||
<span class="identifier">MyVector</span> <span class="special">*</span><span class="identifier">myvector</span> <span class="special">=</span>
|
||
<span class="identifier">segment</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">MyVector</span><span class="special">></span>
|
||
<span class="special">(</span><span class="string">"MyVector"</span><span class="special">)/*</span><span class="identifier">object</span> <span class="identifier">name</span><span class="special">*/</span>
|
||
<span class="special">(</span><span class="identifier">begVal</span> <span class="comment">/*first ctor parameter*/</span><span class="special">,</span>
|
||
<span class="identifier">endVal</span> <span class="comment">/*second ctor parameter*/</span><span class="special">,</span>
|
||
<span class="identifier">alloc_inst</span> <span class="comment">/*third ctor parameter*/</span><span class="special">);</span>
|
||
|
||
<span class="comment">//Use vector as your want</span>
|
||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">sort</span><span class="special">(</span><span class="identifier">myvector</span><span class="special">-></span><span class="identifier">rbegin</span><span class="special">(),</span> <span class="identifier">myvector</span><span class="special">-></span><span class="identifier">rend</span><span class="special">());</span>
|
||
<span class="comment">// . . .</span>
|
||
<span class="comment">//When done, destroy and delete vector from the segment</span>
|
||
<span class="identifier">segment</span><span class="special">.</span><span class="identifier">destroy</span><span class="special"><</span><span class="identifier">MyVector</span><span class="special">>(</span><span class="string">"MyVector"</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>
|
||
<p>
|
||
These containers also show how easy is to create/modify an existing container
|
||
making possible to place it in shared memory.
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="interprocess.allocators_containers.containers_explained.where_allocate"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.containers_explained.where_allocate" title="Where is this being allocated?">Where
|
||
is this being allocated?</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
<span class="bold"><strong>Boost.Interprocess</strong></span> containers are placed
|
||
in shared memory/memory mapped files, etc... using two mechanisms <span class="bold"><strong>at the same time</strong></span>:
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||
<li class="listitem">
|
||
<span class="bold"><strong>Boost.Interprocess </strong></span><code class="computeroutput"><span class="identifier">construct</span><span class="special"><></span></code>, <code class="computeroutput"><span class="identifier">find_or_construct</span><span class="special"><></span></code>... functions. These functions
|
||
place a C++ object in the shared memory/memory mapped file. But this
|
||
places only the object, but <span class="bold"><strong>not</strong></span> the
|
||
memory that this object may allocate dynamically.
|
||
</li>
|
||
<li class="listitem">
|
||
Shared memory allocators. These allow allocating shared memory/memory
|
||
mapped file portions so that containers can allocate dynamically fragments
|
||
of memory to store newly inserted elements.
|
||
</li>
|
||
</ul></div>
|
||
<p>
|
||
This means that to place any <span class="bold"><strong>Boost.Interprocess</strong></span>
|
||
container (including <span class="bold"><strong>Boost.Interprocess</strong></span>
|
||
strings) in shared memory or memory mapped files, containers <span class="bold"><strong>must</strong></span>:
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||
<li class="listitem">
|
||
Define their template allocator parameter to a <span class="bold"><strong>Boost.Interprocess</strong></span>
|
||
allocator.
|
||
</li>
|
||
<li class="listitem">
|
||
Every container constructor must take the <span class="bold"><strong>Boost.Interprocess</strong></span>
|
||
allocator as parameter.
|
||
</li>
|
||
<li class="listitem">
|
||
You must use construct<>/find_or_construct<>... functions
|
||
to place the container in the managed memory.
|
||
</li>
|
||
</ul></div>
|
||
<p>
|
||
If you do the first two points but you don't use <code class="computeroutput"><span class="identifier">construct</span><span class="special"><></span></code> or <code class="computeroutput"><span class="identifier">find_or_construct</span><span class="special"><></span></code> you are creating a container placed
|
||
<span class="bold"><strong>only</strong></span> in your process but that allocates
|
||
memory for contained types from shared memory/memory mapped file.
|
||
</p>
|
||
<p>
|
||
Let's see an example:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">string</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
|
||
<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
|
||
<span class="special">{</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="comment">//Typedefs</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</span><span class="keyword">char</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="identifier">CharAllocator</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">basic_string</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">char_traits</span><span class="special"><</span><span class="keyword">char</span><span class="special">>,</span> <span class="identifier">CharAllocator</span><span class="special">></span>
|
||
<span class="identifier">MyShmString</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</span><span class="identifier">MyShmString</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="identifier">StringAllocator</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">vector</span><span class="special"><</span><span class="identifier">MyShmString</span><span class="special">,</span> <span class="identifier">StringAllocator</span><span class="special">></span>
|
||
<span class="identifier">MyShmStringVector</span><span class="special">;</span>
|
||
|
||
<span class="comment">//Open shared memory</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="identifier">managed_shared_memory</span> <span class="identifier">shm</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="number">10000</span><span class="special">);</span>
|
||
|
||
<span class="comment">//Create allocators</span>
|
||
<span class="identifier">CharAllocator</span> <span class="identifier">charallocator</span> <span class="special">(</span><span class="identifier">shm</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">());</span>
|
||
<span class="identifier">StringAllocator</span> <span class="identifier">stringallocator</span><span class="special">(</span><span class="identifier">shm</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">());</span>
|
||
|
||
<span class="comment">//This string is in only in this process (the pointer pointing to the</span>
|
||
<span class="comment">//buffer that will hold the text is not in shared memory).</span>
|
||
<span class="comment">//But the buffer that will hold "this is my text" is allocated from</span>
|
||
<span class="comment">//shared memory</span>
|
||
<span class="identifier">MyShmString</span> <span class="identifier">mystring</span><span class="special">(</span><span class="identifier">charallocator</span><span class="special">);</span>
|
||
<span class="identifier">mystring</span> <span class="special">=</span> <span class="string">"this is my text"</span><span class="special">;</span>
|
||
|
||
<span class="comment">//This vector is only in this process (the pointer pointing to the</span>
|
||
<span class="comment">//buffer that will hold the MyShmString-s is not in shared memory).</span>
|
||
<span class="comment">//But the buffer that will hold 10 MyShmString-s is allocated from</span>
|
||
<span class="comment">//shared memory using StringAllocator. Since strings use a shared</span>
|
||
<span class="comment">//memory allocator (CharAllocator) the 10 buffers that hold</span>
|
||
<span class="comment">//"this is my text" text are also in shared memory.</span>
|
||
<span class="identifier">MyShmStringVector</span> <span class="identifier">myvector</span><span class="special">(</span><span class="identifier">stringallocator</span><span class="special">);</span>
|
||
<span class="identifier">myvector</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">myvector</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">10</span><span class="special">,</span> <span class="identifier">mystring</span><span class="special">);</span>
|
||
|
||
<span class="comment">//This vector is fully constructed in shared memory. All pointers</span>
|
||
<span class="comment">//buffers are constructed in the same shared memory segment</span>
|
||
<span class="comment">//This vector can be safely accessed from other processes.</span>
|
||
<span class="identifier">MyShmStringVector</span> <span class="special">*</span><span class="identifier">myshmvector</span> <span class="special">=</span>
|
||
<span class="identifier">shm</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">MyShmStringVector</span><span class="special">>(</span><span class="string">"myshmvector"</span><span class="special">)(</span><span class="identifier">stringallocator</span><span class="special">);</span>
|
||
<span class="identifier">myshmvector</span><span class="special">-></span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">myshmvector</span><span class="special">-></span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">10</span><span class="special">,</span> <span class="identifier">mystring</span><span class="special">);</span>
|
||
|
||
<span class="comment">//Destroy vector. This will free all strings that the vector contains</span>
|
||
<span class="identifier">shm</span><span class="special">.</span><span class="identifier">destroy_ptr</span><span class="special">(</span><span class="identifier">myshmvector</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 class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="interprocess.allocators_containers.containers_explained.containers_and_move"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.containers_explained.containers_and_move" title="Move semantics in Interprocess containers">Move
|
||
semantics in Interprocess containers</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
<span class="bold"><strong>Boost.Interprocess</strong></span> containers support
|
||
move semantics, which means that the contents of a container can be moved
|
||
from a container to another one, without any copying. The contents of the
|
||
source container are transferred to the target container and the source
|
||
container is left in default-constructed state.
|
||
</p>
|
||
<p>
|
||
When using containers of containers, we can also use move-semantics to
|
||
insert objects in the container, avoiding unnecessary copies.
|
||
</p>
|
||
<p>
|
||
To transfer the contents of a container to another one, use <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">()</span></code>
|
||
function, as shown in the example. For more details about functions supporting
|
||
move-semantics, see the reference section of Boost.Interprocess containers:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">string</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</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="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="comment">//Typedefs</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">segment_manager</span> <span class="identifier">SegmentManager</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">SegmentManager</span><span class="special">></span> <span class="identifier">CharAllocator</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">basic_string</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">char_traits</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span>
|
||
<span class="special">,</span><span class="identifier">CharAllocator</span><span class="special">></span> <span class="identifier">MyShmString</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</span><span class="identifier">MyShmString</span><span class="special">,</span> <span class="identifier">SegmentManager</span><span class="special">></span> <span class="identifier">StringAllocator</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">vector</span><span class="special"><</span><span class="identifier">MyShmString</span><span class="special">,</span> <span class="identifier">StringAllocator</span><span class="special">></span> <span class="identifier">MyShmStringVector</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="identifier">managed_shared_memory</span> <span class="identifier">shm</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="number">10000</span><span class="special">);</span>
|
||
|
||
<span class="comment">//Create allocators</span>
|
||
<span class="identifier">CharAllocator</span> <span class="identifier">charallocator</span> <span class="special">(</span><span class="identifier">shm</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">());</span>
|
||
<span class="identifier">StringAllocator</span> <span class="identifier">stringallocator</span><span class="special">(</span><span class="identifier">shm</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">());</span>
|
||
|
||
<span class="comment">//Create a vector of strings in shared memory.</span>
|
||
<span class="identifier">MyShmStringVector</span> <span class="special">*</span><span class="identifier">myshmvector</span> <span class="special">=</span>
|
||
<span class="identifier">shm</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">MyShmStringVector</span><span class="special">>(</span><span class="string">"myshmvector"</span><span class="special">)(</span><span class="identifier">stringallocator</span><span class="special">);</span>
|
||
|
||
<span class="comment">//Insert 50 strings in shared memory. The strings will be allocated</span>
|
||
<span class="comment">//only once and no string copy-constructor will be called when inserting</span>
|
||
<span class="comment">//strings, leading to a great performance.</span>
|
||
<span class="identifier">MyShmString</span> <span class="identifier">string_to_compare</span><span class="special">(</span><span class="identifier">charallocator</span><span class="special">);</span>
|
||
<span class="identifier">string_to_compare</span> <span class="special">=</span> <span class="string">"this is a long, long, long, long, long, long, string..."</span><span class="special">;</span>
|
||
|
||
<span class="identifier">myshmvector</span><span class="special">-></span><span class="identifier">reserve</span><span class="special">(</span><span class="number">50</span><span class="special">);</span>
|
||
<span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="number">50</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">){</span>
|
||
<span class="identifier">MyShmString</span> <span class="identifier">move_me</span><span class="special">(</span><span class="identifier">string_to_compare</span><span class="special">);</span>
|
||
<span class="comment">//In the following line, no string copy-constructor will be called.</span>
|
||
<span class="comment">//"move_me"'s contents will be transferred to the string created in</span>
|
||
<span class="comment">//the vector</span>
|
||
<span class="identifier">myshmvector</span><span class="special">-></span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">move_me</span><span class="special">));</span>
|
||
|
||
<span class="comment">//The source string is in default constructed state</span>
|
||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">move_me</span><span class="special">.</span><span class="identifier">empty</span><span class="special">());</span>
|
||
|
||
<span class="comment">//The newly created string will be equal to the "move_me"'s old contents</span>
|
||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">myshmvector</span><span class="special">-></span><span class="identifier">back</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">string_to_compare</span><span class="special">);</span>
|
||
<span class="special">}</span>
|
||
|
||
<span class="comment">//Now erase a string...</span>
|
||
<span class="identifier">myshmvector</span><span class="special">-></span><span class="identifier">pop_back</span><span class="special">();</span>
|
||
|
||
<span class="comment">//...And insert one in the first position.</span>
|
||
<span class="comment">//No string copy-constructor or assignments will be called, but</span>
|
||
<span class="comment">//move constructors and move-assignments. No memory allocation</span>
|
||
<span class="comment">//function will be called in this operations!!</span>
|
||
<span class="identifier">myshmvector</span><span class="special">-></span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">myshmvector</span><span class="special">-></span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">string_to_compare</span><span class="special">));</span>
|
||
|
||
<span class="comment">//Destroy vector. This will free all strings that the vector contains</span>
|
||
<span class="identifier">shm</span><span class="special">.</span><span class="identifier">destroy_ptr</span><span class="special">(</span><span class="identifier">myshmvector</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 class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="interprocess.allocators_containers.containers_explained.containers_of_containers"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.containers_explained.containers_of_containers" title="Containers of containers">Containers
|
||
of containers</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
When creating containers of containers, each container needs an allocator.
|
||
To avoid using several allocators with complex type definitions, we can
|
||
take advantage of the type erasure provided by void allocators and the
|
||
ability to implicitly convert void allocators in allocators that allocate
|
||
other types.
|
||
</p>
|
||
<p>
|
||
Here we have an example that builds a map in shared memory. Key is a string
|
||
and the mapped type is a class that stores several containers:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">map</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">string</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></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="comment">//Typedefs of allocators and containers</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">segment_manager</span> <span class="identifier">segment_manager_t</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">segment_manager_t</span><span class="special">></span> <span class="identifier">void_allocator</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">segment_manager_t</span><span class="special">></span> <span class="identifier">int_allocator</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">int_allocator</span><span class="special">></span> <span class="identifier">int_vector</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</span><span class="identifier">int_vector</span><span class="special">,</span> <span class="identifier">segment_manager_t</span><span class="special">></span> <span class="identifier">int_vector_allocator</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">vector</span><span class="special"><</span><span class="identifier">int_vector</span><span class="special">,</span> <span class="identifier">int_vector_allocator</span><span class="special">></span> <span class="identifier">int_vector_vector</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">segment_manager_t</span><span class="special">></span> <span class="identifier">char_allocator</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">basic_string</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">char_traits</span><span class="special"><</span><span class="keyword">char</span><span class="special">>,</span> <span class="identifier">char_allocator</span><span class="special">></span> <span class="identifier">char_string</span><span class="special">;</span>
|
||
|
||
<span class="keyword">class</span> <span class="identifier">complex_data</span>
|
||
<span class="special">{</span>
|
||
<span class="keyword">int</span> <span class="identifier">id_</span><span class="special">;</span>
|
||
<span class="identifier">char_string</span> <span class="identifier">char_string_</span><span class="special">;</span>
|
||
<span class="identifier">int_vector_vector</span> <span class="identifier">int_vector_vector_</span><span class="special">;</span>
|
||
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="comment">//Since void_allocator is convertible to any other allocator<T>, we can simplify</span>
|
||
<span class="comment">//the initialization taking just one allocator for all inner containers.</span>
|
||
<span class="identifier">complex_data</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">id</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">void_allocator</span> <span class="special">&</span><span class="identifier">void_alloc</span><span class="special">)</span>
|
||
<span class="special">:</span> <span class="identifier">id_</span><span class="special">(</span><span class="identifier">id</span><span class="special">),</span> <span class="identifier">char_string_</span><span class="special">(</span><span class="identifier">name</span><span class="special">,</span> <span class="identifier">void_alloc</span><span class="special">),</span> <span class="identifier">int_vector_vector_</span><span class="special">(</span><span class="identifier">void_alloc</span><span class="special">)</span>
|
||
<span class="special">{}</span>
|
||
<span class="comment">//Other members...</span>
|
||
<span class="special">};</span>
|
||
|
||
<span class="comment">//Definition of the map holding a string as key and complex_data as mapped type</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="keyword">const</span> <span class="identifier">char_string</span><span class="special">,</span> <span class="identifier">complex_data</span><span class="special">></span> <span class="identifier">map_value_type</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">char_string</span><span class="special">,</span> <span class="identifier">complex_data</span><span class="special">></span> <span class="identifier">movable_to_map_value_type</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</span><span class="identifier">map_value_type</span><span class="special">,</span> <span class="identifier">segment_manager_t</span><span class="special">></span> <span class="identifier">map_value_type_allocator</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">map</span><span class="special"><</span> <span class="identifier">char_string</span><span class="special">,</span> <span class="identifier">complex_data</span>
|
||
<span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span><span class="special"><</span><span class="identifier">char_string</span><span class="special">>,</span> <span class="identifier">map_value_type_allocator</span><span class="special">></span> <span class="identifier">complex_map_type</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="number">65536</span><span class="special">);</span>
|
||
|
||
<span class="comment">//An allocator convertible to any allocator<T, segment_manager_t> type</span>
|
||
<span class="identifier">void_allocator</span> <span class="identifier">alloc_inst</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">//Construct the shared memory map and fill it</span>
|
||
<span class="identifier">complex_map_type</span> <span class="special">*</span><span class="identifier">mymap</span> <span class="special">=</span> <span class="identifier">segment</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">complex_map_type</span><span class="special">></span>
|
||
<span class="comment">//(object name), (first ctor parameter, second ctor parameter)</span>
|
||
<span class="special">(</span><span class="string">"MyMap"</span><span class="special">)(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span><span class="special"><</span><span class="identifier">char_string</span><span class="special">>(),</span> <span class="identifier">alloc_inst</span><span class="special">);</span>
|
||
|
||
<span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="number">100</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">){</span>
|
||
<span class="comment">//Both key(string) and value(complex_data) need an allocator in their constructors</span>
|
||
<span class="identifier">char_string</span> <span class="identifier">key_object</span><span class="special">(</span><span class="identifier">alloc_inst</span><span class="special">);</span>
|
||
<span class="identifier">complex_data</span> <span class="identifier">mapped_object</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="string">"default_name"</span><span class="special">,</span> <span class="identifier">alloc_inst</span><span class="special">);</span>
|
||
<span class="identifier">map_value_type</span> <span class="identifier">value</span><span class="special">(</span><span class="identifier">key_object</span><span class="special">,</span> <span class="identifier">mapped_object</span><span class="special">);</span>
|
||
<span class="comment">//Modify values and insert them in the map</span>
|
||
<span class="identifier">mymap</span><span class="special">-></span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">value</span><span class="special">);</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.additional_containers"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.additional_containers" title="Boost containers compatible with Boost.Interprocess">Boost
|
||
containers compatible with Boost.Interprocess</a>
|
||
</h3></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.additional_containers.unordered">Boost
|
||
unordered containers</a></span></dt>
|
||
<dt><span class="section"><a href="allocators_containers.html#interprocess.allocators_containers.additional_containers.multi_index">Boost.MultiIndex
|
||
containers</a></span></dt>
|
||
</dl></div>
|
||
<p>
|
||
As mentioned, container developers might need to change their implementation
|
||
to make them compatible with Boost.Interprocess, because implementation usually
|
||
ignore allocators with smart pointers. Hopefully several Boost containers
|
||
are compatible with <span class="bold"><strong>Interprocess</strong></span>.
|
||
</p>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="interprocess.allocators_containers.additional_containers.unordered"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.additional_containers.unordered" title="Boost unordered containers">Boost
|
||
unordered containers</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
<span class="bold"><strong>Boost.Unordered</strong></span> containers are compatible
|
||
with Interprocess, so programmers can store hash containers in shared memory
|
||
and memory mapped files. Here is a small example storing <code class="computeroutput"><span class="identifier">unordered_map</span></code> in shared memory:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
|
||
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">unordered_map</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">//boost::unordered_map</span>
|
||
|
||
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">functional</span><span class="special">></span> <span class="comment">//std::equal_to</span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container_hash</span><span class="special">/</span><span class="identifier">hash</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">//boost::hash</span>
|
||
|
||
|
||
<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
|
||
<span class="special">{</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="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="number">65536</span><span class="special">);</span>
|
||
|
||
<span class="comment">//Note that unordered_map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,</span>
|
||
<span class="comment">//so the allocator must allocate that pair.</span>
|
||
<span class="keyword">typedef</span> <span class="keyword">int</span> <span class="identifier">KeyType</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="keyword">float</span> <span class="identifier">MappedType</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">float</span><span class="special">></span> <span class="identifier">ValueType</span><span class="special">;</span>
|
||
|
||
<span class="comment">//Typedef the allocator</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</span><span class="identifier">ValueType</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="identifier">ShmemAllocator</span><span class="special">;</span>
|
||
|
||
<span class="comment">//Alias an unordered_map of ints that uses the previous STL-like allocator.</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">unordered_map</span>
|
||
<span class="special"><</span> <span class="identifier">KeyType</span> <span class="special">,</span> <span class="identifier">MappedType</span>
|
||
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hash</span><span class="special"><</span><span class="identifier">KeyType</span><span class="special">></span> <span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">equal_to</span><span class="special"><</span><span class="identifier">KeyType</span><span class="special">></span>
|
||
<span class="special">,</span> <span class="identifier">ShmemAllocator</span><span class="special">></span>
|
||
<span class="identifier">MyHashMap</span><span class="special">;</span>
|
||
|
||
<span class="comment">//Construct a shared memory hash map.</span>
|
||
<span class="comment">//Note that the first parameter is the initial bucket count and</span>
|
||
<span class="comment">//after that, the hash function, the equality function and the allocator</span>
|
||
<span class="identifier">MyHashMap</span> <span class="special">*</span><span class="identifier">myhashmap</span> <span class="special">=</span> <span class="identifier">segment</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">MyHashMap</span><span class="special">>(</span><span class="string">"MyHashMap"</span><span class="special">)</span> <span class="comment">//object name</span>
|
||
<span class="special">(</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hash</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">equal_to</span><span class="special"><</span><span class="keyword">int</span><span class="special">>()</span> <span class="comment">//</span>
|
||
<span class="special">,</span> <span class="identifier">segment</span><span class="special">.</span><span class="identifier">get_allocator</span><span class="special"><</span><span class="identifier">ValueType</span><span class="special">>());</span> <span class="comment">//allocator instance</span>
|
||
|
||
<span class="comment">//Insert data in the hash map</span>
|
||
<span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="number">100</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">){</span>
|
||
<span class="identifier">myhashmap</span><span class="special">-></span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">ValueType</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="special">(</span><span class="keyword">float</span><span class="special">)</span><span class="identifier">i</span><span class="special">));</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 class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="interprocess.allocators_containers.additional_containers.multi_index"></a><a class="link" href="allocators_containers.html#interprocess.allocators_containers.additional_containers.multi_index" title="Boost.MultiIndex containers">Boost.MultiIndex
|
||
containers</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
The widely used <span class="bold"><strong>Boost.MultiIndex</strong></span> library
|
||
is compatible with <span class="bold"><strong>Boost.Interprocess</strong></span>
|
||
so we can construct pretty good databases in shared memory. Constructing
|
||
databases in shared memory is a bit tougher than in normal memory, usually
|
||
because those databases contain strings and those strings need to be placed
|
||
in shared memory. Shared memory strings require an allocator in their constructors
|
||
so this usually makes object insertion a bit more complicated.
|
||
</p>
|
||
<p>
|
||
Here is an example that shows how to put a multi index container in shared
|
||
memory:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">string</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
|
||
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multi_index_container</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multi_index</span><span class="special">/</span><span class="identifier">member</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multi_index</span><span class="special">/</span><span class="identifier">ordered_index</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></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">namespace</span> <span class="identifier">bmi</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multi_index</span><span class="special">;</span>
|
||
|
||
<span class="keyword">typedef</span> <span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">allocator</span><span class="special"><</span><span class="keyword">char</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">char_allocator</span><span class="special">;</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">basic_string</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">char_traits</span><span class="special"><</span><span class="keyword">char</span><span class="special">>,</span> <span class="identifier">char_allocator</span><span class="special">></span><span class="identifier">shm_string</span><span class="special">;</span>
|
||
|
||
<span class="comment">//Data to insert in shared memory</span>
|
||
<span class="keyword">struct</span> <span class="identifier">employee</span>
|
||
<span class="special">{</span>
|
||
<span class="keyword">int</span> <span class="identifier">id</span><span class="special">;</span>
|
||
<span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span>
|
||
<span class="identifier">shm_string</span> <span class="identifier">name</span><span class="special">;</span>
|
||
<span class="identifier">employee</span><span class="special">(</span> <span class="keyword">int</span> <span class="identifier">id_</span>
|
||
<span class="special">,</span> <span class="keyword">int</span> <span class="identifier">age_</span>
|
||
<span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">name_</span>
|
||
<span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_allocator</span> <span class="special">&</span><span class="identifier">a</span><span class="special">)</span>
|
||
<span class="special">:</span> <span class="identifier">id</span><span class="special">(</span><span class="identifier">id_</span><span class="special">),</span> <span class="identifier">age</span><span class="special">(</span><span class="identifier">age_</span><span class="special">),</span> <span class="identifier">name</span><span class="special">(</span><span class="identifier">name_</span><span class="special">,</span> <span class="identifier">a</span><span class="special">)</span>
|
||
<span class="special">{}</span>
|
||
<span class="special">};</span>
|
||
|
||
<span class="comment">//Tags</span>
|
||
<span class="keyword">struct</span> <span class="identifier">id</span><span class="special">{};</span>
|
||
<span class="keyword">struct</span> <span class="identifier">age</span><span class="special">{};</span>
|
||
<span class="keyword">struct</span> <span class="identifier">name</span><span class="special">{};</span>
|
||
|
||
<span class="comment">// Define a multi_index_container of employees with following indices:</span>
|
||
<span class="comment">// - a unique index sorted by employee::int,</span>
|
||
<span class="comment">// - a non-unique index sorted by employee::name,</span>
|
||
<span class="comment">// - a non-unique index sorted by employee::age.</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">bmi</span><span class="special">::</span><span class="identifier">multi_index_container</span><span class="special"><</span>
|
||
<span class="identifier">employee</span><span class="special">,</span>
|
||
<span class="identifier">bmi</span><span class="special">::</span><span class="identifier">indexed_by</span><span class="special"><</span>
|
||
<span class="identifier">bmi</span><span class="special">::</span><span class="identifier">ordered_unique</span>
|
||
<span class="special"><</span><span class="identifier">bmi</span><span class="special">::</span><span class="identifier">tag</span><span class="special"><</span><span class="identifier">id</span><span class="special">>,</span> <span class="identifier">bmi</span><span class="special">::</span><span class="identifier">member</span><span class="special"><</span><span class="identifier">employee</span><span class="special">,</span><span class="keyword">int</span><span class="special">,&</span><span class="identifier">employee</span><span class="special">::</span><span class="identifier">id</span><span class="special">></span> <span class="special">>,</span>
|
||
<span class="identifier">bmi</span><span class="special">::</span><span class="identifier">ordered_non_unique</span><span class="special"><</span>
|
||
<span class="identifier">bmi</span><span class="special">::</span><span class="identifier">tag</span><span class="special"><</span><span class="identifier">name</span><span class="special">>,</span> <span class="identifier">bmi</span><span class="special">::</span><span class="identifier">member</span><span class="special"><</span><span class="identifier">employee</span><span class="special">,</span><span class="identifier">shm_string</span><span class="special">,&</span><span class="identifier">employee</span><span class="special">::</span><span class="identifier">name</span><span class="special">></span> <span class="special">>,</span>
|
||
<span class="identifier">bmi</span><span class="special">::</span><span class="identifier">ordered_non_unique</span>
|
||
<span class="special"><</span><span class="identifier">bmi</span><span class="special">::</span><span class="identifier">tag</span><span class="special"><</span><span class="identifier">age</span><span class="special">>,</span> <span class="identifier">bmi</span><span class="special">::</span><span class="identifier">member</span><span class="special"><</span><span class="identifier">employee</span><span class="special">,</span><span class="keyword">int</span><span class="special">,&</span><span class="identifier">employee</span><span class="special">::</span><span class="identifier">age</span><span class="special">></span> <span class="special">></span> <span class="special">>,</span>
|
||
<span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">allocator</span><span class="special"><</span><span class="identifier">employee</span><span class="special">>::</span><span class="identifier">type</span>
|
||
<span class="special">></span> <span class="identifier">employee_set</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="number">65536</span><span class="special">);</span>
|
||
|
||
<span class="comment">//Construct the multi_index in shared memory</span>
|
||
<span class="identifier">employee_set</span> <span class="special">*</span><span class="identifier">es</span> <span class="special">=</span> <span class="identifier">segment</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">employee_set</span><span class="special">></span>
|
||
<span class="special">(</span><span class="string">"My MultiIndex Container"</span><span class="special">)</span> <span class="comment">//Container's name in shared memory</span>
|
||
<span class="special">(</span> <span class="identifier">employee_set</span><span class="special">::</span><span class="identifier">ctor_args_list</span><span class="special">()</span>
|
||
<span class="special">,</span> <span class="identifier">segment</span><span class="special">.</span><span class="identifier">get_allocator</span><span class="special"><</span><span class="identifier">employee</span><span class="special">>());</span> <span class="comment">//Ctor parameters</span>
|
||
|
||
<span class="comment">//Now insert elements</span>
|
||
<span class="identifier">char_allocator</span> <span class="identifier">ca</span><span class="special">(</span><span class="identifier">segment</span><span class="special">.</span><span class="identifier">get_allocator</span><span class="special"><</span><span class="keyword">char</span><span class="special">>());</span>
|
||
<span class="identifier">es</span><span class="special">-></span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">employee</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="number">31</span><span class="special">,</span> <span class="string">"Joe"</span><span class="special">,</span> <span class="identifier">ca</span><span class="special">));</span>
|
||
<span class="identifier">es</span><span class="special">-></span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">employee</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="number">27</span><span class="special">,</span> <span class="string">"Robert"</span><span class="special">,</span> <span class="identifier">ca</span><span class="special">));</span>
|
||
<span class="identifier">es</span><span class="special">-></span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">employee</span><span class="special">(</span><span class="number">2</span><span class="special">,</span><span class="number">40</span><span class="special">,</span> <span class="string">"John"</span><span class="special">,</span> <span class="identifier">ca</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>
|
||
<p>
|
||
Programmers can place <span class="bold"><strong>Boost.CircularBuffer</strong></span>
|
||
containers in sharecd memory provided they disable debugging facilities with
|
||
defines <code class="computeroutput"><span class="identifier">BOOST_CB_DISABLE_DEBUG</span></code>
|
||
or the more general <code class="computeroutput"><span class="identifier">NDEBUG</span></code>.
|
||
The reason is that those debugging facilities are only compatible with raw
|
||
pointers.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||
<td align="left"></td>
|
||
<td align="right"><div class="copyright-footer">Copyright © 2005-2015 Ion Gaztanaga<p>
|
||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||
</p>
|
||
</div></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>
|
||
</body>
|
||
</html>
|