boost-react-native-bundle
Version:
Boost library as in https://sourceforge.net/projects/boost/files/boost/1.57.0/
611 lines (573 loc) • 245 kB
HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Synchronization mechanisms</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../interprocess.html" title="Chapter 14. Boost.Interprocess">
<link rel="prev" href="offset_ptr.html" title="Mapping Address Independent Pointer: offset_ptr">
<link rel="next" href="managed_memory_segments.html" title="Managed Memory Segments">
</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="offset_ptr.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="managed_memory_segments.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.synchronization_mechanisms"></a><a class="link" href="synchronization_mechanisms.html" title="Synchronization mechanisms">Synchronization
mechanisms</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.synchronization_mechanisms_overview">Synchronization
mechanisms overview</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes">Mutexes</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.conditions">Conditions</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.semaphores">Semaphores</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.sharable_upgradable_mutexes">Sharable
and Upgradable Mutexes</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.lock_conversions">Lock
Transfers Through Move Semantics</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.file_lock">File
Locks</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.message_queue">Message
Queue</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="interprocess.synchronization_mechanisms.synchronization_mechanisms_overview"></a><a class="link" href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.synchronization_mechanisms_overview" title="Synchronization mechanisms overview">Synchronization
mechanisms overview</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.synchronization_mechanisms_overview.synchronization_mechanisms_named_vs_anonymous">Named
And Anonymous Synchronization Mechanisms</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.synchronization_mechanisms_overview.synchronization_mechanisms_types">Types
Of Synchronization Mechanisms</a></span></dt>
</dl></div>
<p>
As mentioned before, the ability to shared memory between processes through
memory mapped files or shared memory objects is not very useful if the access
to that memory can't be effectively synchronized. This is the same problem
that happens with thread-synchronization mechanisms, where heap memory and
global variables are shared between threads, but the access to these resources
needs to be synchronized typically through mutex and condition variables.
<span class="bold"><strong>Boost.Threads</strong></span> implements these synchronization
utilities between threads inside the same process. <span class="bold"><strong>Boost.Interprocess</strong></span>
implements similar mechanisms to synchronize threads from different processes.
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="interprocess.synchronization_mechanisms.synchronization_mechanisms_overview.synchronization_mechanisms_named_vs_anonymous"></a><a class="link" href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.synchronization_mechanisms_overview.synchronization_mechanisms_named_vs_anonymous" title="Named And Anonymous Synchronization Mechanisms">Named
And Anonymous Synchronization Mechanisms</a>
</h4></div></div></div>
<p>
<span class="bold"><strong>Boost.Interprocess</strong></span> presents two types
of synchronization objects:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Named utilities</strong></span>: When two processes
want to create an object of such type, both processes must <span class="emphasis"><em>create</em></span>
or <span class="emphasis"><em>open</em></span> an object using the same name. This is
similar to creating or opening files: a process creates a file with
using a <code class="computeroutput"><span class="identifier">fstream</span></code> with
the name <span class="emphasis"><em>filename</em></span> and another process opens that
file using another <code class="computeroutput"><span class="identifier">fstream</span></code>
with the same <span class="emphasis"><em>filename</em></span> argument. <span class="bold"><strong>Each
process uses a different object to access to the resource, but both
processes are using the same underlying resource</strong></span>.
</li>
<li class="listitem">
<span class="bold"><strong>Anonymous utilities</strong></span>: Since these utilities
have no name, two processes must share <span class="bold"><strong>the same
object</strong></span> through shared memory or memory mapped files. This
is similar to traditional thread synchronization objects: <span class="bold"><strong>Both processes share the same object</strong></span>. Unlike
thread synchronization, where global variables and heap memory is shared
between threads of the same process, sharing objects between two threads
from different process can be only possible through mapped regions
that map the same mappable resource (for example, shared memory or
memory mapped files).
</li>
</ul></div>
<p>
Each type has it's own advantages and disadvantages:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Named utilities are easier to handle for simple synchronization tasks,
since both process don't have to create a shared memory region and
construct the synchronization mechanism there.
</li>
<li class="listitem">
Anonymous utilities can be serialized to disk when using memory mapped
objects obtaining automatic persistence of synchronization utilities.
One could construct a synchronization utility in a memory mapped file,
reboot the system, map the file again, and use the synchronization
utility again without any problem. This can't be achieved with named
synchronization utilities.
</li>
</ul></div>
<p>
The main interface difference between named and anonymous utilities are
the constructors. Usually anonymous utilities have only one constructor,
whereas the named utilities have several constructors whose first argument
is a special type that requests creation, opening or opening or creation
of the underlying resource:
</p>
<pre class="programlisting"><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">//Create the synchronization utility. If it previously</span>
<span class="comment">//exists, throws an error</span>
<span class="identifier">NamedUtility</span><span class="special">(</span><span class="identifier">create_only</span><span class="special">,</span> <span class="special">...)</span>
<span class="comment">//Open the synchronization utility. If it does not previously</span>
<span class="comment">//exist, it's created.</span>
<span class="identifier">NamedUtility</span><span class="special">(</span><span class="identifier">open_or_create</span><span class="special">,</span> <span class="special">...)</span>
<span class="comment">//Open the synchronization utility. If it does not previously</span>
<span class="comment">//exist, throws an error.</span>
<span class="identifier">NamedUtility</span><span class="special">(</span><span class="identifier">open_only</span><span class="special">,</span> <span class="special">...)</span>
</pre>
<p>
On the other hand the anonymous synchronization utility can only be created
and the processes must synchronize using other mechanisms who creates the
utility:
</p>
<pre class="programlisting"><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">//Create the synchronization utility.</span>
<span class="identifier">AnonymousUtility</span><span class="special">(...)</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="interprocess.synchronization_mechanisms.synchronization_mechanisms_overview.synchronization_mechanisms_types"></a><a class="link" href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.synchronization_mechanisms_overview.synchronization_mechanisms_types" title="Types Of Synchronization Mechanisms">Types
Of Synchronization Mechanisms</a>
</h4></div></div></div>
<p>
Apart from its named/anonymous nature, <span class="bold"><strong>Boost.Interprocess</strong></span>
presents the following synchronization utilities:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Mutexes (named and anonymous)
</li>
<li class="listitem">
Condition variables (named and anonymous)
</li>
<li class="listitem">
Semaphores (named and anonymous)
</li>
<li class="listitem">
Upgradable mutexes
</li>
<li class="listitem">
File locks
</li>
</ul></div>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="interprocess.synchronization_mechanisms.mutexes"></a><a class="link" href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes" title="Mutexes">Mutexes</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes.mutexes_whats_a_mutex">What's
A Mutex?</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes.mutexes_mutex_operations">Mutex
Operations</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes.mutexes_interprocess_mutexes">Boost.Interprocess
Mutex Types And Headers</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes.mutexes_scoped_lock">Scoped
lock</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes.mutexes_anonymous_example">Anonymous
mutex example</a></span></dt>
<dt><span class="section"><a href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes.mutexes_named_example">Named
mutex example</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="interprocess.synchronization_mechanisms.mutexes.mutexes_whats_a_mutex"></a><a class="link" href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes.mutexes_whats_a_mutex" title="What's A Mutex?">What's
A Mutex?</a>
</h4></div></div></div>
<p>
<span class="emphasis"><em>Mutex</em></span> stands for <span class="bold"><strong>mut</strong></span>ual
<span class="bold"><strong>ex</strong></span>clusion and it's the most basic form
of synchronization between processes. Mutexes guarantee that only one thread
can lock a given mutex. If a code section is surrounded by a mutex locking
and unlocking, it's guaranteed that only a thread at a time executes that
section of code. When that thread <span class="bold"><strong>unlocks</strong></span>
the mutex, other threads can enter to that code region:
</p>
<pre class="programlisting"><span class="comment">//The mutex has been previously constructed</span>
<span class="identifier">lock_the_mutex</span><span class="special">();</span>
<span class="comment">//This code will be executed only by one thread</span>
<span class="comment">//at a time.</span>
<span class="identifier">unlock_the_mutex</span><span class="special">();</span>
</pre>
<p>
A mutex can also be <span class="bold"><strong>recursive</strong></span> or <span class="bold"><strong>non-recursive</strong></span>:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Recursive mutexes can be locked several times by the same thread. To
fully unlock the mutex, the thread has to unlock the mutex the same
times it has locked it.
</li>
<li class="listitem">
Non-recursive mutexes can't be locked several times by the same thread.
If a mutex is locked twice by a thread, the result is undefined, it
might throw an error or the thread could be blocked forever.
</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="interprocess.synchronization_mechanisms.mutexes.mutexes_mutex_operations"></a><a class="link" href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes.mutexes_mutex_operations" title="Mutex Operations">Mutex
Operations</a>
</h4></div></div></div>
<p>
All the mutex types from <span class="bold"><strong>Boost.Interprocess</strong></span>
implement the following operations:
</p>
<div class="sidebar">
<div class="titlepage"></div>
<p>
<span class="emphasis"><em><span class="bold"><strong>void lock()</strong></span></em></span>
</p>
</div>
<p>
<span class="bold"><strong>Effects:</strong></span> The calling thread tries to obtain
ownership of the mutex, and if another thread has ownership of the mutex,
it waits until it can obtain the ownership. If a thread takes ownership
of the mutex the mutex must be unlocked by the same thread. If the mutex
supports recursive locking, the mutex must be unlocked the same number
of times it is locked.
</p>
<p>
<span class="bold"><strong>Throws:</strong></span> <span class="bold"><strong>interprocess_exception</strong></span>
on error.
</p>
<div class="sidebar">
<div class="titlepage"></div>
<p>
<span class="emphasis"><em><span class="bold"><strong>bool try_lock()</strong></span></em></span>
</p>
</div>
<p>
<span class="bold"><strong>Effects:</strong></span> The calling thread tries to obtain
ownership of the mutex, and if another thread has ownership of the mutex
returns immediately. If the mutex supports recursive locking, the mutex
must be unlocked the same number of times it is locked.
</p>
<p>
<span class="bold"><strong>Returns:</strong></span> If the thread acquires ownership
of the mutex, returns true, if the another thread has ownership of the
mutex, returns false.
</p>
<p>
<span class="bold"><strong>Throws:</strong></span> <span class="bold"><strong>interprocess_exception</strong></span>
on error.
</p>
<div class="sidebar">
<div class="titlepage"></div>
<p>
<span class="emphasis"><em><span class="bold"><strong>bool timed_lock(const boost::posix_time::ptime
&abs_time)</strong></span></em></span>
</p>
</div>
<p>
<span class="bold"><strong>Effects:</strong></span> The calling thread will try to
obtain exclusive ownership of the mutex if it can do so in until the specified
time is reached. If the mutex supports recursive locking, the mutex must
be unlocked the same number of times it is locked.
</p>
<p>
<span class="bold"><strong>Returns:</strong></span> If the thread acquires ownership
of the mutex, returns true, if the timeout expires returns false.
</p>
<p>
<span class="bold"><strong>Throws:</strong></span> <span class="bold"><strong>interprocess_exception</strong></span>
on error.
</p>
<div class="sidebar">
<div class="titlepage"></div>
<p>
<span class="emphasis"><em><span class="bold"><strong>void unlock()</strong></span></em></span>
</p>
</div>
<p>
<span class="bold"><strong>Precondition:</strong></span> The thread must have exclusive
ownership of the mutex.
</p>
<p>
<span class="bold"><strong>Effects:</strong></span> The calling thread releases the
exclusive ownership of the mutex. If the mutex supports recursive locking,
the mutex must be unlocked the same number of times it is locked.
</p>
<p>
<span class="bold"><strong>Throws:</strong></span> An exception derived from <span class="bold"><strong>interprocess_exception</strong></span> on error.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span></code> absolute time points used by
Boost.Interprocess synchronization mechanisms are UTC time points, not
local time points
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="interprocess.synchronization_mechanisms.mutexes.mutexes_interprocess_mutexes"></a><a class="link" href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes.mutexes_interprocess_mutexes" title="Boost.Interprocess Mutex Types And Headers">Boost.Interprocess
Mutex Types And Headers</a>
</h4></div></div></div>
<p>
Boost.Interprocess offers the following mutex types:
</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">sync</span><span class="special">/</span><span class="identifier">interprocess_mutex</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"><a class="link" href="../boost/interprocess/interprocess_mutex.html" title="Class interprocess_mutex">interprocess_mutex</a></code>:
A non-recursive, anonymous mutex that can be placed in shared memory
or memory mapped files.
</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">sync</span><span class="special">/</span><span class="identifier">interprocess_recursive_mutex</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"><a class="link" href="../boost/interprocess/interprocess_r_idp66640512.html" title="Class interprocess_recursive_mutex">interprocess_recursive_mutex</a></code>:
A recursive, anonymous mutex that can be placed in shared memory or
memory mapped files.
</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">sync</span><span class="special">/</span><span class="identifier">named_mutex</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"><a class="link" href="../boost/interprocess/named_mutex.html" title="Class named_mutex">named_mutex</a></code>:
A non-recursive, named mutex.
</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">sync</span><span class="special">/</span><span class="identifier">named_recursive_mutex</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"><a class="link" href="../boost/interprocess/named_recursive_mutex.html" title="Class named_recursive_mutex">named_recursive_mutex</a></code>:
A recursive, named mutex.
</li></ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="interprocess.synchronization_mechanisms.mutexes.mutexes_scoped_lock"></a><a class="link" href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes.mutexes_scoped_lock" title="Scoped lock">Scoped
lock</a>
</h4></div></div></div>
<p>
It's very important to unlock a mutex after the process has read or written
the data. This can be difficult when dealing with exceptions, so usually
mutexes are used with a scoped lock, a class that can guarantee that a
mutex will always be unlocked even when an exception occurs. To use a scoped
lock just include:
</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">sync</span><span class="special">/</span><span class="identifier">scoped_lock</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
</pre>
<p>
Basically, a scoped lock calls <span class="bold"><strong>unlock()</strong></span>
in its destructor, and a mutex is always unlocked when an exception occurs.
Scoped lock has many constructors to lock, try_lock, timed_lock a mutex
or not to lock it at all.
</p>
<pre class="programlisting"><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">//Let's create any mutex type:</span>
<span class="identifier">MutexType</span> <span class="identifier">mutex</span><span class="special">;</span>
<span class="special">{</span>
<span class="comment">//This will lock the mutex</span>
<span class="identifier">scoped_lock</span><span class="special"><</span><span class="identifier">MutexType</span><span class="special">></span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">mutex</span><span class="special">);</span>
<span class="comment">//Some code</span>
<span class="comment">//The mutex will be unlocked here</span>
<span class="special">}</span>
<span class="special">{</span>
<span class="comment">//This will try_lock the mutex</span>
<span class="identifier">scoped_lock</span><span class="special"><</span><span class="identifier">MutexType</span><span class="special">></span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">mutex</span><span class="special">,</span> <span class="identifier">try_to_lock</span><span class="special">);</span>
<span class="comment">//Check if the mutex has been successfully locked</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">lock</span><span class="special">){</span>
<span class="comment">//Some code</span>
<span class="special">}</span>
<span class="comment">//If the mutex was locked it will be unlocked</span>
<span class="special">}</span>
<span class="special">{</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span> <span class="identifier">abs_time</span> <span class="special">=</span> <span class="special">...</span>
<span class="comment">//This will timed_lock the mutex</span>
<span class="identifier">scoped_lock</span><span class="special"><</span><span class="identifier">MutexType</span><span class="special">></span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">mutex</span><span class="special">,</span> <span class="identifier">abs_time</span><span class="special">);</span>
<span class="comment">//Check if the mutex has been successfully locked</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">lock</span><span class="special">){</span>
<span class="comment">//Some code</span>
<span class="special">}</span>
<span class="comment">//If the mutex was locked it will be unlocked</span>
<span class="special">}</span>
</pre>
<p>
For more information, check the <code class="computeroutput"><a class="link" href="../boost/interprocess/scoped_lock.html" title="Class template scoped_lock">scoped_lock's
reference</a></code>.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span></code> absolute time points used by
Boost.Interprocess synchronization mechanisms are UTC time points, not
local time points
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="interprocess.synchronization_mechanisms.mutexes.mutexes_anonymous_example"></a><a class="link" href="synchronization_mechanisms.html#interprocess.synchronization_mechanisms.mutexes.mutexes_anonymous_example" title="Anonymous mutex example">Anonymous
mutex example</a>
</h4></div></div></div>
<p>
Imagine that two processes need to write traces to a cyclic buffer built
in shared memory. Each process needs to obtain exclusive access to the
cyclic buffer, write the trace and continue.
</p>
<p>
To protect the cyclic buffer, we can store a process shared mutex in the
cyclic buffer. Each process will lock the mutex before writing the data
and will write a flag when ends writing the traces (<code class="computeroutput"><span class="identifier">doc_anonymous_mutex_shared_data</span><span class="special">.</span><span class="identifier">hpp</span></code>
header):
</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">sync</span><span class="special">/</span><span class="identifier">interprocess_mutex</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
<span class="keyword">struct</span> <span class="identifier">shared_memory_log</span>
<span class="special">{</span>
<span class="keyword">enum</span> <span class="special">{</span> <span class="identifier">NumItems</span> <span class="special">=</span> <span class="number">100</span> <span class="special">};</span>
<span class="keyword">enum</span> <span class="special">{</span> <span class="identifier">LineSize</span> <span class="special">=</span> <span class="number">100</span> <span class="special">};</span>
<span class="identifier">shared_memory_log</span><span class="special">()</span>
<span class="special">:</span> <span class="identifier">current_line</span><span class="special">(</span><span class="number">0</span><span class="special">)</span>
<span class="special">,</span> <span class="identifier">end_a</span><span class="special">(</span><span class="keyword">false</span><span class="special">)</span>
<span class="special">,</span> <span class="identifier">end_b</span><span class="special">(</span><span class="keyword">false</span><span class="special">)</span>
<span class="special">{}</span>
<span class="comment">//Mutex to protect access to the queue</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">interprocess_mutex</span> <span class="identifier">mutex</span><span class="special">;</span>
<span class="comment">//Items to fill</span>
<span class="keyword">char</span> <span class="identifier">items</span><span class="special">[</span><span class="identifier">NumItems</span><span class="special">][</span><span class="identifier">LineSize</span><span class="special">];</span>
<span class="keyword">int</span> <span class="identifier">current_line</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">end_a</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">end_b</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
This is the process main process. Creates the shared memory, constructs
the cyclic buffer and start writing traces:
</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">shared_memory_object</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">mapped_region</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">sync</span><span class="special">/</span><span class="identifier">scoped_lock</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
<span class="preprocessor">#include</span> <span class="string">"doc_anonymous_mutex_shared_data.hpp"</span>
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cstdio</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="keyword">try</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 a shared memory object.</span>
<span class="identifier">shared_memory_object</span> <span class="identifier">shm</span>
<span class="special">(</span><span class="identifier">create_only</span> <span class="comment">//only create</span>
<span class="special">,</span><span class="string">"MySharedMemory"</span> <span class="comment">//name</span>
<span class="special">,</span><span class="identifier">read_write</span> <span class="comment">//read-write mode</span>
<span class="special">);</span>
<span class="comment">//Set size</span>
<span class="identifier">shm</span><span class="special">.</span><span class="identifier">truncate</span><span class="special">(</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">shared_memory_log</span><span class="special">));</span>
<span class="comment">//Map the whole shared memory in this process</span>
<span class="identifier">mapped_region</span> <span class="identifier">region</span>
<span class="special">(</span><span class="identifier">shm</span> <span class="comment">//What to map</span>
<span class="special">,</span><span class="identifier">read_write</span> <span class="comment">//Map it as read-write</span>
<span class="special">);</span>
<span class="comment">//Get the address of the mapped region</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="identifier">addr</span> <span class="special">=</span> <span class="identifier">region</span><span class="special">.</span><span class="identifier">get_address</span><span class="special">();</span>
<span class="comment">//Construct the shared structure in memory</span>
<span class="identifier">shared_memory_log</span> <span class="special">*</span> <span class="identifier">data</span> <span class="special">=</span> <span class="keyword">new</span> <span class="special">(</span><span class="identifier">addr</span><span class="special">)</span> <span class="identifier">shared_memory_log</span><span class="special">;</span>
<span class="comment">//Write some logs</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="identifier">shared_memory_log</span><span class="special">::</span><span class="identifier">NumItems</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">){</span>
<span class="comment">//Lock the mutex</span>
<span class="identifier">scoped_lock</span><span class="special"><</span><span class="identifier">interprocess_mutex</span><span class="special">></span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">data</span><span class="special">-></span><span class="identifier">mutex</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">sprintf</span><span class="special">(</span><span class="identifier">data</span><span class="special">-></span><span class="identifier">items</span><span class="special">[(</span><span class="identifier">data</span><span class="special">-></span><span class="identifier">current_line</span><span class="special">++)</span> <span class="special">%</span> <span class="identifier">shared_memory_log</span><span class="special">::</span><span class="identifier">NumItems</span><span class="special">]</span>
<span class="special">,</span><span class="string">"%s_%d"</span><span class="special">,</span> <span class="string">"process_a"</span><span class="special">,</span> <span class="identifier">i</span><span class="special">);</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">i</span> <span class="special">==</span> <span class="special">(</span><span class="identifier">shared_memory_log</span><span class="special">::</span><span class="identifier">NumItems</span><span class="special">-</span><span class="number">1</span><span class="special">))</span>
<span class="identifier">data</span><span class="special">-></span><span class="identifier">end_a</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
<span class="comment">//Mutex is released here</span>
<span class="special">}</span>
<span class="comment">//Wait until the other process ends</span>
<span class="keyword">while</span><span class="special">(</span><span class="number">1</span><span class="special">){</span>
<span class="identifier">scoped_lock</span><span class="special"><</span><span class="identifier">interprocess_mutex</span><span class="special">></span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">data</span><span class="special">-></span><span class="identifier">mutex</span><span class="special">);</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">data</span><span class="special">-></span><span class="identifier">end_b</span><span class="special">)</span>
<span class="keyword">break</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">interprocess_exception</span> <span class="special">&</span><span class="identifier">ex</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">ex</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="number">1</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>
<p>
The second process opens the shared memory, obtains access to the cyclic
buffer and starts writing traces:
</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">shared_memory_object</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">mapped_region</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">sync</span><span class="special">/</span><span class="identifier">scoped_lock</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
<span class="preprocessor">#include</span> <span class="string">"doc_anonymous_mutex_shared_data.hpp"</span>
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cstdio</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 destruction</span>
<span class="keyword">struct</span> <span class="identifier">shm_remove</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">//Open the shared memory object.</span>
<span class="identifier">shared_memory_object</span> <span class="identifier">shm</span>
<span class="special">(</span><span class="identifier">open_only</span> <span class="comment">//only create</span>
<span class="special">,</span><span class="string">"MySharedMemory"</span> <span class="comment">//name</span>
<span class="special">,</span><span class="identifier">read_write</span> <span class="comment">//read-write mode</span>
<span class="special">);</span>
<span class="comment">//Map the whole shared memory in this process</span>
<span class="identifier">mapped_region</span> <span class="identifier">region</span>
<span class="special">(</span><span class="identifier">shm</span> <span class="comment">//What to map</span>
<span class="special">,</span><span class="identifier">read_write</span> <span class="comment">//Map it as read-write</span>
<span class="special">);</span>
<span class="comment">//Get the address of the mapped region</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="identifier">addr</span> <span class="special">=</span> <span class="identifier">region</span><span class="special">.</span><span class="identifier">get_address</span><span class="special">();</span>
<span class="comment">//Construct the shared structure in memory</span>
<span class="identifier">shared_memory_log</span> <span class="special">*</span> <span class="identifier">data</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">shared_memory_log</span><span class="special">*>(</span><span class="identifier">addr</span><span class="special">);</span>
<span class="comment">//Write some logs</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">//Lock the mutex</span>
<span class="identifier">scoped_lock</span><span class="special"><</span><span class="identifier">interprocess_mutex</span><span class="special">></span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">data</span><span class="special">-></span><span class="identifier">mutex</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">sprintf</span><span class="special">(</span><span class="identifier">data</span><span class="special">-></span><span class="identifier">items</span><span class="special">[(</span><span class="identifier">data</span><span class="special">-></span><span class="identifier">current_line</span><span class="special">++)</span> <span class="special">%</span> <span class="identifier">shared_memory_log</span><span class="special">::</span><span class="identifier">NumItems</span><span class="special">]</span>
<span class="special">,</span><span class="string">"%s_%d"</span><span class="special">,</span> <span class="string">"process_a"</span><span class="special">,</span> <span class="identifier">i</span><span class="special">);</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">i</span> <span class="special">==</span> <span class="special