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=US-ASCII">
|
|
<title>Allocators, containers and memory allocation algorithms</title>
|
|
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
|
|
<meta name="generator" content="DocBook XSL Stylesheets V1.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">functional</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>
|