1
0
Fork 0
cl-sites/w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/html/ShMem.html

466 lines
34 KiB
HTML
Raw Normal View History

2025-01-28 10:11:14 +01:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>3.7. Shared Memory &mdash; Computer Systems Fundamentals</title>
<link rel="stylesheet" href="_static/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
<link rel="stylesheet" href="_static/css/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/css/normalize.css" type="text/css" />
<link rel="stylesheet" href="../../../JSAV/css/JSAV.css" type="text/css" />
<link rel="stylesheet" href="../../../lib/odsaMOD-min.css" type="text/css" />
<link rel="stylesheet" href="_static/css/jquery-1.11.4-smoothness-ui.css" type="text/css" />
<link rel="stylesheet" href="../../../lib/odsaStyle-min.css" type="text/css" />
<link rel="stylesheet" href="_static/css/csf.css" type="text/css" />
<style>
.underline { text-decoration: underline; }
</style>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.4.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [['$','$'], ['\\(','\\)']],
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
processEscapes: true
},
"HTML-CSS": {
scale: "80"
}
});
</script>
<link rel="shortcut icon" href="_static/favicon.ico"/>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="index" title="Computer Systems Fundamentals" href="index.html" />
<link rel="next" title="8. Semaphores" href="IPCSems.html" />
<link rel="prev" title="6. Message Passing With Message Queues" href="MQueues.html" />
</head><body>
<nav class="navbar navbar-expand-md navbar-dark navbar-custom fixed-top">
<a class="navbar-brand py-0" href="index.html"><img src="_static/CSF-Logo-Square-Text.png" alt="OpenCSF Logo" height="40em" class="py-1 px-2 mb-0 align-center rounded-lg bg-white" /></a>
<!-- Show a navbar toggler on mobile -->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#defaultNavbars" aria-controls="defaultNavbars" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="defaultNavbars">
<ul class="navbar-nav mr-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle jmu-gold rounded" href="ShMem.html#" id="navbarDropdownChapters" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Contents</a>
<div class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="navbarDropdownChapters">
<a class="dropdown-item" tabindex="-1" href="ShMem.html#"><b>Chapter 1</b></a>
<a class="dropdown-item" href="IntroConcSysOverview.html">&nbsp;&nbsp;&nbsp;1.1. Introduction to Concurrent Systems</a>
<a class="dropdown-item" href="SysAndModels.html">&nbsp;&nbsp;&nbsp;1.2. Systems and Models</a>
<a class="dropdown-item" href="Themes.html">&nbsp;&nbsp;&nbsp;1.3. Themes and Guiding Principles</a>
<a class="dropdown-item" href="Architectures.html">&nbsp;&nbsp;&nbsp;1.4. System Architectures</a>
<a class="dropdown-item" href="StateModels.html">&nbsp;&nbsp;&nbsp;1.5. State Models in UML</a>
<a class="dropdown-item" href="SequenceModels.html">&nbsp;&nbsp;&nbsp;1.6. Sequence Models in UML</a>
<a class="dropdown-item" href="StateModelImplementation.html">&nbsp;&nbsp;&nbsp;1.7. Extended Example: State Model Implementation</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 2</b></a>
<a class="dropdown-item" href="ProcessesOverview.html">&nbsp;&nbsp;&nbsp;2.1. Processes and OS Basics</a>
<a class="dropdown-item" href="Multiprogramming.html">&nbsp;&nbsp;&nbsp;2.2. Processes and Multiprogramming</a>
<a class="dropdown-item" href="KernelMechanics.html">&nbsp;&nbsp;&nbsp;2.3. Kernel Mechanics</a>
<a class="dropdown-item" href="Syscall.html">&nbsp;&nbsp;&nbsp;2.4. System Call Interface</a>
<a class="dropdown-item" href="ProcessCycle.html">&nbsp;&nbsp;&nbsp;2.5. Process Life Cycle</a>
<a class="dropdown-item" href="UnixFile.html">&nbsp;&nbsp;&nbsp;2.6. The UNIX File Abstraction</a>
<a class="dropdown-item" href="EventsSignals.html">&nbsp;&nbsp;&nbsp;2.7. Events and Signals</a>
<a class="dropdown-item" href="Extended2Processes.html">&nbsp;&nbsp;&nbsp;2.8. Extended Example: Listing Files with Processes</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 3</b></a>
<a class="dropdown-item" href="IPCOverview.html">&nbsp;&nbsp;&nbsp;3.1. Concurrency with IPC</a>
<a class="dropdown-item" href="IPCModels.html">&nbsp;&nbsp;&nbsp;3.2. IPC Models</a>
<a class="dropdown-item" href="Pipes.html">&nbsp;&nbsp;&nbsp;3.3. Pipes and FIFOs</a>
<a class="dropdown-item" href="MMap.html">&nbsp;&nbsp;&nbsp;3.4. Shared Memory With Memory-mapped Files</a>
<a class="dropdown-item" href="POSIXvSysV.html">&nbsp;&nbsp;&nbsp;3.5. POSIX vs. System V IPC</a>
<a class="dropdown-item" href="MQueues.html">&nbsp;&nbsp;&nbsp;3.6. Message Passing With Message Queues</a>
<a class="dropdown-item" href="ShMem.html">&nbsp;&nbsp;&nbsp;3.7. Shared Memory</a>
<a class="dropdown-item" href="IPCSems.html">&nbsp;&nbsp;&nbsp;3.8. Semaphores</a>
<a class="dropdown-item" href="Extended3Bash.html">&nbsp;&nbsp;&nbsp;3.9. Extended Example: Bash-lite: A Simple Command-line Shell</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 4</b></a>
<a class="dropdown-item" href="SocketsOverview.html">&nbsp;&nbsp;&nbsp;4.1. Networked Concurrency</a>
<a class="dropdown-item" href="FiveLayer.html">&nbsp;&nbsp;&nbsp;4.2. The TCP/IP Internet Model</a>
<a class="dropdown-item" href="NetApps.html">&nbsp;&nbsp;&nbsp;4.3. Network Applications and Protocols</a>
<a class="dropdown-item" href="Sockets.html">&nbsp;&nbsp;&nbsp;4.4. The Socket Interface</a>
<a class="dropdown-item" href="TCPSockets.html">&nbsp;&nbsp;&nbsp;4.5. TCP Socket Programming: HTTP</a>
<a class="dropdown-item" href="UDPSockets.html">&nbsp;&nbsp;&nbsp;4.6. UDP Socket Programming: DNS</a>
<a class="dropdown-item" href="AppBroadcast.html">&nbsp;&nbsp;&nbsp;4.7. Application-Layer Broadcasting: DHCP</a>
<a class="dropdown-item" href="Extended4CGI.html">&nbsp;&nbsp;&nbsp;4.8. Extended Example: CGI Web Server</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 5</b></a>
<a class="dropdown-item" href="InternetOverview.html">&nbsp;&nbsp;&nbsp;5.1. The Internet and Connectivity</a>
<a class="dropdown-item" href="AppLayer.html">&nbsp;&nbsp;&nbsp;5.2. Application Layer: Overlay Networks</a>
<a class="dropdown-item" href="TransLayer.html">&nbsp;&nbsp;&nbsp;5.3. Transport Layer</a>
<a class="dropdown-item" href="NetSec.html">&nbsp;&nbsp;&nbsp;5.4. Network Security Fundamentals</a>
<a class="dropdown-item" href="NetLayer.html">&nbsp;&nbsp;&nbsp;5.5. Network Layer: IP</a>
<a class="dropdown-item" href="LinkLayer.html">&nbsp;&nbsp;&nbsp;5.6. Link Layer</a>
<a class="dropdown-item" href="Wireless.html">&nbsp;&nbsp;&nbsp;5.7. Wireless Connectivity: Wi-Fi, Bluetooth, and Zigbee</a>
<a class="dropdown-item" href="Extended5DNS.html">&nbsp;&nbsp;&nbsp;5.8. Extended Example: DNS client</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 6</b></a>
<a class="dropdown-item" href="ThreadsOverview.html">&nbsp;&nbsp;&nbsp;6.1. Concurrency with Multithreading</a>
<a class="dropdown-item" href="ProcVThreads.html">&nbsp;&nbsp;&nbsp;6.2. Processes vs. Threads</a>
<a class="dropdown-item" href="RaceConditions.html">&nbsp;&nbsp;&nbsp;6.3. Race Conditions and Critical Sections</a>
<a class="dropdown-item" href="POSIXThreads.html">&nbsp;&nbsp;&nbsp;6.4. POSIX Thread Library</a>
<a class="dropdown-item" href="ThreadArgs.html">&nbsp;&nbsp;&nbsp;6.5. Thread Arguments and Return Values</a>
<a class="dropdown-item" href="ImplicitThreads.html">&nbsp;&nbsp;&nbsp;6.6. Implicit Threading and Language-based Threads</a>
<a class="dropdown-item" href="Extended6Input.html">&nbsp;&nbsp;&nbsp;6.7. Extended Example: Keyboard Input Listener</a>
<a class="dropdown-item" href="Extended6Primes.html">&nbsp;&nbsp;&nbsp;6.8. Extended Example: Concurrent Prime Number Search</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 7</b></a>
<a class="dropdown-item" href="SynchOverview.html">&nbsp;&nbsp;&nbsp;7.1. Synchronization Primitives</a>
<a class="dropdown-item" href="CritSect.html">&nbsp;&nbsp;&nbsp;7.2. Critical Sections and Peterson's Solution</a>
<a class="dropdown-item" href="Locks.html">&nbsp;&nbsp;&nbsp;7.3. Locks</a>
<a class="dropdown-item" href="Semaphores.html">&nbsp;&nbsp;&nbsp;7.4. Semaphores</a>
<a class="dropdown-item" href="Barriers.html">&nbsp;&nbsp;&nbsp;7.5. Barriers</a>
<a class="dropdown-item" href="Condvars.html">&nbsp;&nbsp;&nbsp;7.6. Condition Variables</a>
<a class="dropdown-item" href="Deadlock.html">&nbsp;&nbsp;&nbsp;7.7. Deadlock</a>
<a class="dropdown-item" href="Extended7Events.html">&nbsp;&nbsp;&nbsp;7.8. Extended Example: Event Log File</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 8</b></a>
<a class="dropdown-item" href="SynchProblemsOverview.html">&nbsp;&nbsp;&nbsp;8.1. Synchronization Patterns and Problems</a>
<a class="dropdown-item" href="SynchDesign.html">&nbsp;&nbsp;&nbsp;8.2. Basic Synchronization Design Patterns</a>
<a class="dropdown-item" href="ProdCons.html">&nbsp;&nbsp;&nbsp;8.3. Producer-Consumer Problem</a>
<a class="dropdown-item" href="ReadWrite.html">&nbsp;&nbsp;&nbsp;8.4. Readers-Writers Problem</a>
<a class="dropdown-item" href="DiningPhil.html">&nbsp;&nbsp;&nbsp;8.5. Dining Philosophers Problem and Deadlock</a>
<a class="dropdown-item" href="CigSmokers.html">&nbsp;&nbsp;&nbsp;8.6. Cigarette Smokers Problem and the Limits of Semaphores and Locks</a>
<a class="dropdown-item" href="Extended8ModExp.html">&nbsp;&nbsp;&nbsp;8.7. Extended Example: Parallel Modular Exponentiation</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 9</b></a>
<a class="dropdown-item" href="ParallelDistributedOverview.html">&nbsp;&nbsp;&nbsp;9.1. Parallel and Distributed Systems</a>
<a class="dropdown-item" href="ParVConc.html">&nbsp;&nbsp;&nbsp;9.2. Parallelism vs. Concurrency</a>
<a class="dropdown-item" href="ParallelDesign.html">&nbsp;&nbsp;&nbsp;9.3. Parallel Design Patterns</a>
<a class="dropdown-item" href="Scaling.html">&nbsp;&nbsp;&nbsp;9.4. Limits of Parallelism and Scaling</a>
<a class="dropdown-item" href="DistTiming.html">&nbsp;&nbsp;&nbsp;9.5. Timing in Distributed Environments</a>
<a class="dropdown-item" href="DistDataStorage.html">&nbsp;&nbsp;&nbsp;9.6. Reliable Data Storage and Location</a>
<a class="dropdown-item" href="DistConsensus.html">&nbsp;&nbsp;&nbsp;9.7. Consensus in Distributed Systems</a>
<a class="dropdown-item" href="Extended9Blockchain.html">&nbsp;&nbsp;&nbsp;9.8. Extended Example: Blockchain Proof-of-Work</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Appendix A</b></a>
<a class="dropdown-item" href="CLangOverview.html">&nbsp;&nbsp;&nbsp;A.1. C Language Reintroduction</a>
<a class="dropdown-item" href="Debugging.html">&nbsp;&nbsp;&nbsp;A.2. Documentation and Debugging</a>
<a class="dropdown-item" href="BasicTypes.html">&nbsp;&nbsp;&nbsp;A.3. Basic Types and Pointers</a>
<a class="dropdown-item" href="Arrays.html">&nbsp;&nbsp;&nbsp;A.4. Arrays, Structs, Enums, and Type Definitions</a>
<a class="dropdown-item" href="Functions.html">&nbsp;&nbsp;&nbsp;A.5. Functions and Scope</a>
<a class="dropdown-item" href="Pointers.html">&nbsp;&nbsp;&nbsp;A.6. Pointers and Dynamic Allocation</a>
<a class="dropdown-item" href="Strings.html">&nbsp;&nbsp;&nbsp;A.7. Strings</a>
<a class="dropdown-item" href="FunctionPointers.html">&nbsp;&nbsp;&nbsp;A.8. Function Pointers</a>
<a class="dropdown-item" href="Files.html">&nbsp;&nbsp;&nbsp;A.9. Files</a>
</div>
</li>
</ul>
</div>
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
<li class="nav-item"><a class="nav-link jmu-gold" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/source/ShMem.rst"
target="_blank" rel="nofollow">Show Source</a></li>
</ul>
</nav>
<div class="container center">
«&#160;&#160;<a id="prevmod" href="MQueues.html">3.6. Message Passing With Message Queues</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod" href="IPCSems.html">3.8. Semaphores</a>&#160;&#160;»
</div>
<br />
<script type="text/javascript" src="_static/js/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript" src="_static/js/jquery-1.11.4-ui.min.js"></script>
<script type="text/javascript" src="_static/js/forge-0.7.0.min.js"></script>
<script type="text/javascript" src="../../../JSAV/lib/jquery.transit.js"></script>
<script type="text/javascript" src="../../../JSAV/lib/raphael.js"></script>
<script type="text/javascript" src="../../../JSAV/build/JSAV-min.js"></script>
<script type="text/javascript" src="_static/js/config.js"></script>
<script type="text/javascript" src="../../../lib/odsaUtils-min.js"></script>
<script type="text/javascript" src="../../../lib/odsaMOD-min.js"></script>
<script type="text/javascript" src="_static/js/d3-4.13.0.min.js"></script>
<script type="text/javascript" src="_static/js/d3-selection-multi.v1.min.js"></script>
<script type="text/javascript" src="../../../lib/dataStructures.js"></script>
<div class="container">
<script>ODSA.SETTINGS.DISP_MOD_COMP = true;ODSA.SETTINGS.MODULE_NAME = "ShMem";ODSA.SETTINGS.MODULE_LONG_NAME = "Shared Memory";ODSA.SETTINGS.MODULE_CHAPTER = "Concurrency with IPC"; ODSA.SETTINGS.BUILD_DATE = "2021-06-01 15:31:50"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="shared-memory">
<h1>3.7. Shared Memory<a class="headerlink" href="ShMem.html#shared-memory" title="Permalink to this headline"></a></h1>
<div class="figure mb-2 align-right" id="id2" style="width: 40%">
<span id="ipcshmem"></span><a class="reference internal image-reference" href="_images/CSF-Images.3.6.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="A shared memory region present in two processes" src="_images/CSF-Images.3.6.png" style="width: 90%;" /></a>
<p class="caption align-center px-3"><span class="caption-text"> Figure 3.7.1: A shared memory region present in two processes</span></p>
</div>
<p>Setting up <a class="reference internal" href="Glossary.html#term-shared-memory"><span class="xref std std-term">shared memory</span></a> with the techniques in this section is very similar to using
<a class="reference internal" href="Glossary.html#term-memory-mapped-file"><span class="xref std std-term">memory-mapped files</span></a>, with the exception that there is no pre-defined
persistent file. That is, shared memory can be set up to allow for immediate data exchange between
processes without having a persistent record of the communication. <a href="ShMem.html#ipcshmem">Figure 3.7.1</a>
illustrates the logical structure of a shared memory region that is mapped into two different processes.</p>
<p>For applications that exchange large amounts of data, shared memory is far superior to
message-passing techniques like message queues, which require system calls for every data exchange.
The major disadvantage of shared memory is that the processes must take extra precaution to
synchronize access to the region. If process A writes into the shared region, that might cause
unstable behavior in process B, or vice versa.</p>
<div class="topic border border-dark rounded-lg alert-danger px-2 mb-3">
<div class="figure align-left">
<a class="reference internal image-reference" href="_images/CSF-Images-BugWarning.png"><img alt="Decorative bug warning" src="_images/CSF-Images-BugWarning.png" style="width: 90%;" /></a>
</div>
<p class="topic-title first pt-2 mb-1">Bug Warning</p><hr class="mt-1" />
<p>When a shared memory region is established in two or more processes, there is no guarantee that the
regions will be placed at the same base address. For instance, one process might have the shared
region starting at address <code class="docutils literal notranslate"><span class="pre">0x40000000</span></code> while the other process uses <code class="docutils literal notranslate"><span class="pre">0x50008000</span></code>. It is
critical to understand that these two addresses refer to the exact same piece of data. So storing
the number 1 in the first processs address <code class="docutils literal notranslate"><span class="pre">0x40000000</span></code> means the second process has the value
of 1 at <code class="docutils literal notranslate"><span class="pre">0x50008000</span></code>. The two (different) addresses refer to the exact same location.</p>
<p>Given that the base addresses are different, all elements in the region must also have different
addresses. The implication of this is that shared memory regions cannot use pointers to refer to
other parts of the region. For instance, assume the shared memory contains a linked list with the
first node at the beginning of the region. The next node appears 256 bytes later. Using the
addresses above, in one process, <code class="docutils literal notranslate"><span class="pre">0x40000000</span></code> must contain a pointer to address <code class="docutils literal notranslate"><span class="pre">0x40000100</span></code>;
in the other address, the pointer must point to <code class="docutils literal notranslate"><span class="pre">0x50008100</span></code>, given the different base address.
This means that the beginning of the shared memory region must simultaneously store <cite>two different</cite>
values, which is impossible.</p>
<p>The solution is to avoid the use of pointers within the shared memory region, using pointer
arithmetic instead. That is, if <code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">*baseaddr</span></code> is declared to point to the base address of the
region, then the two processes would need to use <code class="docutils literal notranslate"><span class="pre">*(baseaddr</span> <span class="pre">+</span> <span class="pre">256)</span></code> to refer to the next node of
the linked list. Or, as an alternative, avoid linked lists entirely and use a contiguous data
structure instead.</p>
</div>
<div class="section" id="posix-shared-memory">
<h2>3.7.1. POSIX Shared Memory<a class="headerlink" href="ShMem.html#posix-shared-memory" title="Permalink to this headline"></a></h2>
<p>The POSIX interface for shared memory is very simple, consisting of two primary functions. The
<code class="docutils literal notranslate"><span class="pre">shm_open()</span></code> takes the POSIX IPC object name, a bit-mask of flags (<code class="docutils literal notranslate"><span class="pre">oflag</span></code>) and a permission
mode to apply new objects. <a class="footnote-reference" href="ShMem.html#f18" id="id1">[1]</a> Similarly, <code class="docutils literal notranslate"><span class="pre">shm_unlink()</span></code> deletes the shared memory object.</p>
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
<div class="figure align-left">
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
</div>
<p class="topic-title first pt-2 mb-1">C library functions &lt;sys/mman.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">shm_open</span> <span class="pre">(const</span> <span class="pre">char</span> <span class="pre">*name,</span> <span class="pre">int</span> <span class="pre">oflag,</span> <span class="pre">mode_t</span> <span class="pre">mode);</span></code></dt>
<dd>Open a connection to a POSIX shared memory object.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">shm_unlink</span> <span class="pre">(const</span> <span class="pre">char</span> <span class="pre">*name);</span></code></dt>
<dd>Delete a POSIX shared memory object.</dd>
</dl>
</div>
<p>The following code sample uses a <code class="docutils literal notranslate"><span class="pre">struct</span></code> declared as follows:</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
2
3
4
5</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="k">struct</span> <span class="n">permission</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">user</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">group</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">other</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</td></tr></table></div>
<p><a class="reference external" href="ShMem.html#cl3-10">Code Listing 3.10</a> sets up a POSIX shared memory object, which is identified by a given name. Note
that the call to <code class="docutils literal notranslate"><span class="pre">shm_open()</span></code> creates the object but does not specify a size; instead,
<code class="docutils literal notranslate"><span class="pre">ftruncate()</span></code> resizes the object to be large enough to store one instance of the <code class="docutils literal notranslate"><span class="pre">struct</span></code>
permission. Next, the process maps the shared memory object into memory with <code class="docutils literal notranslate"><span class="pre">mmap()</span></code> before using
<code class="docutils literal notranslate"><span class="pre">fork()</span></code> to create a child process (which inherits both the shared memory identifier and the
memory mapped region). The child writes to the region before exiting; the parent waits until the
child exits and reads the data.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl3-10"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 3.10:</span>
<span class="cm"> Using POSIX shared memory to exchange data between processes</span>
<span class="cm"> */</span>
<span class="cm">/* Create unsized shared memory object;</span>
<span class="cm"> return value is a file descriptor */</span>
<span class="kt">int</span> <span class="n">shmfd</span> <span class="o">=</span> <span class="n">shm_open</span> <span class="p">(</span><span class="s">&quot;/OpenCSF_SHM&quot;</span><span class="p">,</span> <span class="n">O_CREAT</span> <span class="o">|</span> <span class="n">O_EXCL</span> <span class="o">|</span> <span class="n">O_RDWR</span><span class="p">,</span> <span class="n">S_IRUSR</span> <span class="o">|</span> <span class="n">S_IWUSR</span><span class="p">);</span>
<span class="n">assert</span> <span class="p">(</span><span class="n">shmfd</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="cm">/* Resize the region to store 1 struct instance */</span>
<span class="n">assert</span> <span class="p">(</span><span class="n">ftruncate</span> <span class="p">(</span><span class="n">shmfd</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="k">struct</span> <span class="n">permission</span><span class="p">))</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="cm">/* Map the object into memory so file operations aren&#39;t needed */</span>
<span class="k">struct</span> <span class="n">permission</span> <span class="o">*</span><span class="n">perm</span> <span class="o">=</span> <span class="n">mmap</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="k">struct</span> <span class="n">permission</span><span class="p">),</span>
<span class="n">PROT_READ</span> <span class="o">|</span> <span class="n">PROT_WRITE</span><span class="p">,</span> <span class="n">MAP_SHARED</span><span class="p">,</span> <span class="n">shmfd</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">assert</span> <span class="p">(</span><span class="n">perm</span> <span class="o">!=</span> <span class="n">MAP_FAILED</span><span class="p">);</span>
<span class="cm">/* Create a child process and write to the mapped/shared region */</span>
<span class="kt">pid_t</span> <span class="n">child_pid</span> <span class="o">=</span> <span class="n">fork</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">perm</span><span class="o">-&gt;</span><span class="n">user</span> <span class="o">=</span> <span class="mi">6</span><span class="p">;</span>
<span class="n">perm</span><span class="o">-&gt;</span><span class="n">group</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
<span class="n">perm</span><span class="o">-&gt;</span><span class="n">other</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="cm">/* Unmap and close the child&#39;s shared memory access */</span>
<span class="n">munmap</span> <span class="p">(</span><span class="n">perm</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="k">struct</span> <span class="n">permission</span><span class="p">));</span>
<span class="n">close</span> <span class="p">(</span><span class="n">shmfd</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* Make the parent wait until the child has exited */</span>
<span class="n">wait</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
<span class="cm">/* Read from the mapped/shared memory region */</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Permission bit-mask: 0%d%d%d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">perm</span><span class="o">-&gt;</span><span class="n">user</span><span class="p">,</span> <span class="n">perm</span><span class="o">-&gt;</span><span class="n">group</span><span class="p">,</span> <span class="n">perm</span><span class="o">-&gt;</span><span class="n">other</span><span class="p">);</span>
<span class="cm">/* Unmap, close, and delete the shared memory object */</span>
<span class="n">munmap</span> <span class="p">(</span><span class="n">perm</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="k">struct</span> <span class="n">permission</span><span class="p">));</span>
<span class="n">close</span> <span class="p">(</span><span class="n">shmfd</span><span class="p">);</span>
<span class="n">shm_unlink</span> <span class="p">(</span><span class="s">&quot;/OpenCSF_SHM&quot;</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>Combining <code class="docutils literal notranslate"><span class="pre">shm_open()</span></code> and <code class="docutils literal notranslate"><span class="pre">mmap()</span></code> in this way is a common technique that often confuses
novices. Specifically, it seems redundant to use both IPC mechanisms, because the same task could be
accomplished with either <code class="docutils literal notranslate"><span class="pre">shm_open()</span></code> or <code class="docutils literal notranslate"><span class="pre">mmap()</span></code> (not both). While it is true that both are not
required, combining them leads to certain advantages:</p>
<blockquote>
<div><ul class="simple">
<li>The <code class="docutils literal notranslate"><span class="pre">shm_open()</span></code> parameters adhere to the standard POSIX IPC conventions. This allows the
processes to use POSIX names to identify the objects, rather than creating files in arbitrary locations.</li>
<li>Using <code class="docutils literal notranslate"><span class="pre">shm_unlink()</span></code> provides a safety check that is not guaranteed with creating and mapping
arbitrary files. Specifically, <code class="docutils literal notranslate"><span class="pre">shm_unlink()</span></code> will not delete the object immediately if any other
process also has an open connection; this delay allows decreases the likelihood of other processes
experiencing random and unexpected failures. In contrast, if an arbitrary non-IPC file was used for
the <code class="docutils literal notranslate"><span class="pre">mmap()</span></code>, the timing of the deletion would be determined by the underlying file system; this
introduces unnecessary maintenance and possibly restricts the portability of the program.</li>
<li>Using <code class="docutils literal notranslate"><span class="pre">mmap()</span></code> allows the developer to cast the shared memory object to a more meaningful data
structure type and to avoid using file operations. Specifically, observe that the return type from
<code class="docutils literal notranslate"><span class="pre">shm_open()</span></code> is a file descriptor, which does not provide any information about the type of data
stored in the object. By mapping it into memory, we can cast the pointer returned and access the
<code class="docutils literal notranslate"><span class="pre">user</span></code>, <code class="docutils literal notranslate"><span class="pre">group</span></code>, and <code class="docutils literal notranslate"><span class="pre">other</span></code> fields contained in the <code class="docutils literal notranslate"><span class="pre">struct</span></code>.</li>
</ul>
</div></blockquote>
<table class="docutils footnote" frame="void" id="f18" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="ShMem.html#id1">[1]</a></td><td>As a minor point of terminology, all forms of POSIX IPC, including shared memory, are
referred to as <em>objects</em>. In contrast, System V shared memory is called a “segment” for historical purposes.</td></tr>
</tbody>
</table>
<div
id="IPCShmSumm"
class="embedContainer"
data-exer-name="IPCShmSumm"
data-long-name="IPC shared memory questions"
data-short-name="IPCShmSumm"
data-frame-src="../../../Exercises/IPC/IPCShmSumm.html?selfLoggingEnabled=false&amp;localMode=true&amp;module=ShMem"
data-frame-width="950"
data-frame-height="550"
data-external="false"
data-points="0"
data-required="False"
data-showhide="show"
data-threshold="2"
data-type="ka"
data-exer-id="">
<div class="center">
<div id="IPCShmSumm_iframe"></div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="mt-4 container center">
«&#160;&#160;<a id="prevmod1" href="MQueues.html">3.6. Message Passing With Message Queues</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod1" href="IPCSems.html">3.8. Semaphores</a>&#160;&#160;»
</div>
</div>
<br />
<div class="row jmu-dark-purple-bg">
<div class="col-md-12">
<center>
<a id="contact_us" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="mailto:webmaster@opencsf.org" role="button">Contact Us</a>
<a id="license" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/lib/license.html" target="_blank">License</a>
</center>
</div>
</div>
<script src="_static/js/popper.js-1.14.7-min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="_static/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>