483 lines
36 KiB
HTML
483 lines
36 KiB
HTML
|
|
|||
|
<!DOCTYPE html>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<html lang="en">
|
|||
|
<head>
|
|||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|||
|
|
|||
|
<title>3.4. Shared Memory With Memory-mapped Files — 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="5. POSIX vs. System V IPC" href="POSIXvSysV.html" />
|
|||
|
<link rel="prev" title="3. Pipes and FIFOs" href="Pipes.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="MMap.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="MMap.html#"><b>Chapter 1</b></a>
|
|||
|
<a class="dropdown-item" href="IntroConcSysOverview.html"> 1.1. Introduction to Concurrent Systems</a>
|
|||
|
<a class="dropdown-item" href="SysAndModels.html"> 1.2. Systems and Models</a>
|
|||
|
<a class="dropdown-item" href="Themes.html"> 1.3. Themes and Guiding Principles</a>
|
|||
|
<a class="dropdown-item" href="Architectures.html"> 1.4. System Architectures</a>
|
|||
|
<a class="dropdown-item" href="StateModels.html"> 1.5. State Models in UML</a>
|
|||
|
<a class="dropdown-item" href="SequenceModels.html"> 1.6. Sequence Models in UML</a>
|
|||
|
<a class="dropdown-item" href="StateModelImplementation.html"> 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"> 2.1. Processes and OS Basics</a>
|
|||
|
<a class="dropdown-item" href="Multiprogramming.html"> 2.2. Processes and Multiprogramming</a>
|
|||
|
<a class="dropdown-item" href="KernelMechanics.html"> 2.3. Kernel Mechanics</a>
|
|||
|
<a class="dropdown-item" href="Syscall.html"> 2.4. System Call Interface</a>
|
|||
|
<a class="dropdown-item" href="ProcessCycle.html"> 2.5. Process Life Cycle</a>
|
|||
|
<a class="dropdown-item" href="UnixFile.html"> 2.6. The UNIX File Abstraction</a>
|
|||
|
<a class="dropdown-item" href="EventsSignals.html"> 2.7. Events and Signals</a>
|
|||
|
<a class="dropdown-item" href="Extended2Processes.html"> 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"> 3.1. Concurrency with IPC</a>
|
|||
|
<a class="dropdown-item" href="IPCModels.html"> 3.2. IPC Models</a>
|
|||
|
<a class="dropdown-item" href="Pipes.html"> 3.3. Pipes and FIFOs</a>
|
|||
|
<a class="dropdown-item" href="MMap.html"> 3.4. Shared Memory With Memory-mapped Files</a>
|
|||
|
<a class="dropdown-item" href="POSIXvSysV.html"> 3.5. POSIX vs. System V IPC</a>
|
|||
|
<a class="dropdown-item" href="MQueues.html"> 3.6. Message Passing With Message Queues</a>
|
|||
|
<a class="dropdown-item" href="ShMem.html"> 3.7. Shared Memory</a>
|
|||
|
<a class="dropdown-item" href="IPCSems.html"> 3.8. Semaphores</a>
|
|||
|
<a class="dropdown-item" href="Extended3Bash.html"> 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"> 4.1. Networked Concurrency</a>
|
|||
|
<a class="dropdown-item" href="FiveLayer.html"> 4.2. The TCP/IP Internet Model</a>
|
|||
|
<a class="dropdown-item" href="NetApps.html"> 4.3. Network Applications and Protocols</a>
|
|||
|
<a class="dropdown-item" href="Sockets.html"> 4.4. The Socket Interface</a>
|
|||
|
<a class="dropdown-item" href="TCPSockets.html"> 4.5. TCP Socket Programming: HTTP</a>
|
|||
|
<a class="dropdown-item" href="UDPSockets.html"> 4.6. UDP Socket Programming: DNS</a>
|
|||
|
<a class="dropdown-item" href="AppBroadcast.html"> 4.7. Application-Layer Broadcasting: DHCP</a>
|
|||
|
<a class="dropdown-item" href="Extended4CGI.html"> 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"> 5.1. The Internet and Connectivity</a>
|
|||
|
<a class="dropdown-item" href="AppLayer.html"> 5.2. Application Layer: Overlay Networks</a>
|
|||
|
<a class="dropdown-item" href="TransLayer.html"> 5.3. Transport Layer</a>
|
|||
|
<a class="dropdown-item" href="NetSec.html"> 5.4. Network Security Fundamentals</a>
|
|||
|
<a class="dropdown-item" href="NetLayer.html"> 5.5. Network Layer: IP</a>
|
|||
|
<a class="dropdown-item" href="LinkLayer.html"> 5.6. Link Layer</a>
|
|||
|
<a class="dropdown-item" href="Wireless.html"> 5.7. Wireless Connectivity: Wi-Fi, Bluetooth, and Zigbee</a>
|
|||
|
<a class="dropdown-item" href="Extended5DNS.html"> 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"> 6.1. Concurrency with Multithreading</a>
|
|||
|
<a class="dropdown-item" href="ProcVThreads.html"> 6.2. Processes vs. Threads</a>
|
|||
|
<a class="dropdown-item" href="RaceConditions.html"> 6.3. Race Conditions and Critical Sections</a>
|
|||
|
<a class="dropdown-item" href="POSIXThreads.html"> 6.4. POSIX Thread Library</a>
|
|||
|
<a class="dropdown-item" href="ThreadArgs.html"> 6.5. Thread Arguments and Return Values</a>
|
|||
|
<a class="dropdown-item" href="ImplicitThreads.html"> 6.6. Implicit Threading and Language-based Threads</a>
|
|||
|
<a class="dropdown-item" href="Extended6Input.html"> 6.7. Extended Example: Keyboard Input Listener</a>
|
|||
|
<a class="dropdown-item" href="Extended6Primes.html"> 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"> 7.1. Synchronization Primitives</a>
|
|||
|
<a class="dropdown-item" href="CritSect.html"> 7.2. Critical Sections and Peterson's Solution</a>
|
|||
|
<a class="dropdown-item" href="Locks.html"> 7.3. Locks</a>
|
|||
|
<a class="dropdown-item" href="Semaphores.html"> 7.4. Semaphores</a>
|
|||
|
<a class="dropdown-item" href="Barriers.html"> 7.5. Barriers</a>
|
|||
|
<a class="dropdown-item" href="Condvars.html"> 7.6. Condition Variables</a>
|
|||
|
<a class="dropdown-item" href="Deadlock.html"> 7.7. Deadlock</a>
|
|||
|
<a class="dropdown-item" href="Extended7Events.html"> 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"> 8.1. Synchronization Patterns and Problems</a>
|
|||
|
<a class="dropdown-item" href="SynchDesign.html"> 8.2. Basic Synchronization Design Patterns</a>
|
|||
|
<a class="dropdown-item" href="ProdCons.html"> 8.3. Producer-Consumer Problem</a>
|
|||
|
<a class="dropdown-item" href="ReadWrite.html"> 8.4. Readers-Writers Problem</a>
|
|||
|
<a class="dropdown-item" href="DiningPhil.html"> 8.5. Dining Philosophers Problem and Deadlock</a>
|
|||
|
<a class="dropdown-item" href="CigSmokers.html"> 8.6. Cigarette Smokers Problem and the Limits of Semaphores and Locks</a>
|
|||
|
<a class="dropdown-item" href="Extended8ModExp.html"> 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"> 9.1. Parallel and Distributed Systems</a>
|
|||
|
<a class="dropdown-item" href="ParVConc.html"> 9.2. Parallelism vs. Concurrency</a>
|
|||
|
<a class="dropdown-item" href="ParallelDesign.html"> 9.3. Parallel Design Patterns</a>
|
|||
|
<a class="dropdown-item" href="Scaling.html"> 9.4. Limits of Parallelism and Scaling</a>
|
|||
|
<a class="dropdown-item" href="DistTiming.html"> 9.5. Timing in Distributed Environments</a>
|
|||
|
<a class="dropdown-item" href="DistDataStorage.html"> 9.6. Reliable Data Storage and Location</a>
|
|||
|
<a class="dropdown-item" href="DistConsensus.html"> 9.7. Consensus in Distributed Systems</a>
|
|||
|
<a class="dropdown-item" href="Extended9Blockchain.html"> 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"> A.1. C Language Reintroduction</a>
|
|||
|
<a class="dropdown-item" href="Debugging.html"> A.2. Documentation and Debugging</a>
|
|||
|
<a class="dropdown-item" href="BasicTypes.html"> A.3. Basic Types and Pointers</a>
|
|||
|
<a class="dropdown-item" href="Arrays.html"> A.4. Arrays, Structs, Enums, and Type Definitions</a>
|
|||
|
<a class="dropdown-item" href="Functions.html"> A.5. Functions and Scope</a>
|
|||
|
<a class="dropdown-item" href="Pointers.html"> A.6. Pointers and Dynamic Allocation</a>
|
|||
|
<a class="dropdown-item" href="Strings.html"> A.7. Strings</a>
|
|||
|
<a class="dropdown-item" href="FunctionPointers.html"> A.8. Function Pointers</a>
|
|||
|
<a class="dropdown-item" href="Files.html"> 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/MMap.rst"
|
|||
|
target="_blank" rel="nofollow">Show Source</a></li>
|
|||
|
|
|||
|
</ul>
|
|||
|
</nav>
|
|||
|
|
|||
|
|
|||
|
<div class="container center">
|
|||
|
«  <a id="prevmod" href="Pipes.html">3.3. Pipes and FIFOs</a>
|
|||
|
  ::  
|
|||
|
<a class="uplink" href="index.html">Contents</a>
|
|||
|
  ::  
|
|||
|
<a id="nextmod" href="POSIXvSysV.html">3.5. POSIX vs. System V IPC</a>  »
|
|||
|
|
|||
|
</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 = "MMap";ODSA.SETTINGS.MODULE_LONG_NAME = "Shared Memory With Memory-mapped Files";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-with-memory-mapped-files">
|
|||
|
<h1>3.4. Shared Memory With Memory-mapped Files<a class="headerlink" href="MMap.html#shared-memory-with-memory-mapped-files" title="Permalink to this headline">¶</a></h1>
|
|||
|
<p>A <a class="reference internal" href="Glossary.html#term-memory-mapped-file"><span class="xref std std-term">memory mapping</span></a> is a region of the process’s virtual memory space that is
|
|||
|
mapped in a one-to-one correspondence with another entity. In this section, we will focus
|
|||
|
exclusively on <a class="reference internal" href="Glossary.html#term-memory-mapped-file"><span class="xref std std-term">memory-mapped files</span></a>, where the memory of region
|
|||
|
corresponds to a traditional file on disk. For example, assume that the address <code class="docutils literal notranslate"><span class="pre">0xf77b5000</span></code> is
|
|||
|
mapped to the first byte of a file. Then <code class="docutils literal notranslate"><span class="pre">0xf77b5001</span></code> maps to the second byte, <code class="docutils literal notranslate"><span class="pre">0xf77b5002</span></code> to
|
|||
|
the third, and so on.</p>
|
|||
|
<p>When we say that the file is mapped to a particular region in memory, we mean that the process sets
|
|||
|
up a pointer to the beginning of that region. The process can the dereference that pointer for
|
|||
|
direct access to the contents of the file. Specifically, there is no need to use standard file
|
|||
|
access functions, such as <code class="docutils literal notranslate"><span class="pre">read()</span></code>, <code class="docutils literal notranslate"><span class="pre">write()</span></code>, or <code class="docutils literal notranslate"><span class="pre">fseek()</span></code>. Rather, the file can be accessed
|
|||
|
as if it has already been read into memory as an array of bytes. Memory-mapped files have several
|
|||
|
uses and advantages over traditional file access functions:</p>
|
|||
|
<blockquote>
|
|||
|
<div><ul class="simple">
|
|||
|
<li>Memory-mapped files allow for multiple processes to share read-only access to a common file. As a
|
|||
|
straightforward example, the C standard library (<code class="docutils literal notranslate"><span class="pre">glibc.so</span></code>) is mapped into all processes running
|
|||
|
C programs. As such, only one copy of the file needs to be loaded into physical memory, even if
|
|||
|
there are thousands of programs running.</li>
|
|||
|
<li>In some cases, memory-mapped files simplify the logic of a program by using memory-mapped I/O.
|
|||
|
Rather than using <code class="docutils literal notranslate"><span class="pre">fseek()</span></code> multiple times to jump to random file locations, the data can be
|
|||
|
accessed directly by using an index into an array.</li>
|
|||
|
<li>Memory-mapped files provide more efficient access for initial reads. When <code class="docutils literal notranslate"><span class="pre">read()</span></code> is used to
|
|||
|
access a file, the file contents are first copied from disk into the kernel’s <a class="reference internal" href="Glossary.html#term-buffer-cache"><span class="xref std std-term">buffer cache</span></a>.
|
|||
|
Then, the data must be copied again into the process’s user-mode memory for access. Memory-mapped
|
|||
|
files bypass the buffer cache, and the data is copied directly into the user-mode portion of
|
|||
|
memory.</li>
|
|||
|
<li>If the region is set up to be writable, memory-mapped files provide extremely fast IPC data
|
|||
|
exchange. That is, when one process writes to the region, that data is immediately accessible by
|
|||
|
the other process <cite>without having to invoke a system call</cite>. Note that setting up the regions in
|
|||
|
both processes is an expensive operation in terms of execution time; however, once the region is
|
|||
|
set up, data is exchanged immediately. <a class="footnote-reference" href="MMap.html#f17" id="id1">[1]</a></li>
|
|||
|
<li>In contrast to message-passing forms of IPC (such as <a class="reference internal" href="Glossary.html#term-pipe"><span class="xref std std-term">pipes</span></a>), memory-mapped files
|
|||
|
create persistent IPC. Once the data is written to the shared region, it can be repeatedly accessed
|
|||
|
by other processes. Moreover, the data will eventually be written back to the file on disk for
|
|||
|
long-term storage.</li>
|
|||
|
</ul>
|
|||
|
</div></blockquote>
|
|||
|
<div class="section" id="memory-mapped-files">
|
|||
|
<h2>3.4.1. Memory-mapped Files<a class="headerlink" href="MMap.html#memory-mapped-files" title="Permalink to this headline">¶</a></h2>
|
|||
|
<p>Three functions provide the basic functionality of memory-mapped files. The <code class="docutils literal notranslate"><span class="pre">mmap()</span></code> and
|
|||
|
<code class="docutils literal notranslate"><span class="pre">munmap()</span></code> functions are used to set up or remove a mapping, respectively. Both functions take a
|
|||
|
length parameter that specifies the size of the region. The <code class="docutils literal notranslate"><span class="pre">mmap()</span></code> function also includes
|
|||
|
parameters for the types of actions that can be performed (<code class="docutils literal notranslate"><span class="pre">prot</span></code>), whether the region is private
|
|||
|
or shared with other processes (<code class="docutils literal notranslate"><span class="pre">flags</span></code>), the file descriptor (<code class="docutils literal notranslate"><span class="pre">fd</span></code>), and the byte offset into
|
|||
|
the file that corresponds with the start of the region (<code class="docutils literal notranslate"><span class="pre">offset</span></code>). The <code class="docutils literal notranslate"><span class="pre">addr</span></code> parameter for
|
|||
|
mmap() is typically NULL, allowing the system to determine the address of the region. For
|
|||
|
<code class="docutils literal notranslate"><span class="pre">munmap()</span></code>, the <code class="docutils literal notranslate"><span class="pre">addr</span></code> must be the start of the memory-mapped region (which is the value
|
|||
|
returned by <code class="docutils literal notranslate"><span class="pre">mmap()</span></code>).</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 – <sys/mman.h></p><hr class="mt-1" />
|
|||
|
<dl class="docutils">
|
|||
|
<dt><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">*mmap</span> <span class="pre">(void</span> <span class="pre">*addr,</span> <span class="pre">size_t</span> <span class="pre">length,</span> <span class="pre">int</span> <span class="pre">prot,</span> <span class="pre">int</span> <span class="pre">flags,</span> <span class="pre">int</span> <span class="pre">fd,</span> <span class="pre">off_t</span> <span class="pre">offset);</span></code></dt>
|
|||
|
<dd>Map a file identified by fd into memory at address addr.</dd>
|
|||
|
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">munmap</span> <span class="pre">(void</span> <span class="pre">*addr,</span> <span class="pre">size_t</span> <span class="pre">length);</span></code></dt>
|
|||
|
<dd>Unmap a mapped region.</dd>
|
|||
|
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">msync</span> <span class="pre">(void</span> <span class="pre">*addr,</span> <span class="pre">size_t</span> <span class="pre">length,</span> <span class="pre">int</span> <span class="pre">flags);</span></code></dt>
|
|||
|
<dd>Synchronize mapped region with its underlying file.</dd>
|
|||
|
</dl>
|
|||
|
</div>
|
|||
|
<p>One key issue with memory-mapped files is the timing of when updates get copied back into the file
|
|||
|
on disk. For instance, if another process opens and reads the file using <code class="docutils literal notranslate"><span class="pre">read()</span></code>, will this other
|
|||
|
process have access to any updates that were written to the memory-mapped region? The answer is that
|
|||
|
it depends on a number of timing factors.</p>
|
|||
|
<p>The first factor is the kernel itself. When a file is mapped into memory with <code class="docutils literal notranslate"><span class="pre">mmap()</span></code>, the kernel
|
|||
|
will occasionally trigger a write to copy updated portions back to disk. This write can occur for a
|
|||
|
number of reasons and cannot be predicted. A second factor is the file system of the underlying
|
|||
|
file. Some file systems do not commit changes to the file until the writing process has closed its
|
|||
|
connection to the file. If the writing process still has the file mapped into memory, its connection
|
|||
|
must still be open; as a result, no other process would be able to access any updates written to the
|
|||
|
memory-mapped file.</p>
|
|||
|
<p>Processes can insert control over this issue by using the <code class="docutils literal notranslate"><span class="pre">msync()</span></code> function. This function takes
|
|||
|
a flags parameter that can initiate a synchronous, <a class="reference internal" href="Glossary.html#term-blocking-i-o"><span class="xref std std-term">blocking</span></a> write (<code class="docutils literal notranslate"><span class="pre">MS_SYNC</span></code>) or an
|
|||
|
asynchronous, non-blocking one (<code class="docutils literal notranslate"><span class="pre">MS_ASYNC</span></code>). In the case of the asynchronous write, the data will
|
|||
|
get copied to disk at a later point; however, the updated data would be immediately available to any
|
|||
|
process that reads from the file with <code class="docutils literal notranslate"><span class="pre">read()</span></code>.</p>
|
|||
|
</div>
|
|||
|
<div class="section" id="region-protections-and-privacy">
|
|||
|
<h2>3.4.2. Region Protections and Privacy<a class="headerlink" href="MMap.html#region-protections-and-privacy" title="Permalink to this headline">¶</a></h2>
|
|||
|
<p>When setting up a memory-mapped file, the process must specify the protections that will be
|
|||
|
associated with the region (<code class="docutils literal notranslate"><span class="pre">prot</span></code>). Note that these protections only apply to the current
|
|||
|
process. If another process maps the same file into its virtual memory space, that second process
|
|||
|
may set different protections. As such, it is possible that a region marked as read-only in one
|
|||
|
process <cite>may actually change while the process is running</cite>. <a class="reference external" href="MMap.html#tbl3-2">Table 3.2</a> identifies the protections
|
|||
|
that can be combined as a bit-mask.</p>
|
|||
|
<center>
|
|||
|
<div class="row">
|
|||
|
<div class="col-md-2"> </div>
|
|||
|
<div class="col-md-8">
|
|||
|
<table class="table table-bordered">
|
|||
|
<thead class="jmu-dark-purple-bg text-light">
|
|||
|
<tr>
|
|||
|
<th class="py-0 center">Protection</th>
|
|||
|
<th class="py-0 center">Actions permitted</th>
|
|||
|
</tr>
|
|||
|
</thead>
|
|||
|
<tbody>
|
|||
|
<tr>
|
|||
|
<td class="py-0 center">PROT_NONE</td>
|
|||
|
<td class="py-0">The region may not be accessed</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0 center">PROT_READ</td>
|
|||
|
<td class="py-0">The contents of the region can be read</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0 center">PROT_WRITE</td>
|
|||
|
<td class="py-0">The contents of the region can be modified</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0 center">PROT_EXEC</td>
|
|||
|
<td class="py-0">The contents of the region can be executed</td>
|
|||
|
</tr>
|
|||
|
</tbody>
|
|||
|
</table
|
|||
|
<p>
|
|||
|
Table 3.2: Protection flags for memory-mapped files
|
|||
|
</p>
|
|||
|
</div>
|
|||
|
</center><p>Memory-mapped regions can also be designated as private (<code class="docutils literal notranslate"><span class="pre">MAP_PRIVATE</span></code>) or shared
|
|||
|
(<code class="docutils literal notranslate"><span class="pre">MAP_SHARED</span></code>). When calling <code class="docutils literal notranslate"><span class="pre">mmap()</span></code> exactly one of these two options must be specified for the
|
|||
|
flags parameter. If a region is designated as private, any updates will not be visible to other
|
|||
|
processes that have mapped the same file, and the updates will not be written back to the underlying
|
|||
|
file.</p>
|
|||
|
<p><a class="reference external" href="MMap.html#cl3-6">Code Listing 3.6</a> shows how to map and unmap a file into memory. In this example, we are opening the
|
|||
|
<code class="docutils literal notranslate"><span class="pre">/bin/bash</span></code> executable file on Linux. Linux executables are formatted using the <em>executable
|
|||
|
and linking format (ELF)</em> specification. Part of this specification indicates that the first byte of
|
|||
|
the file must be <code class="docutils literal notranslate"><span class="pre">0x7f</span></code> and the next three bytes are the ASCII characters for <code class="docutils literal notranslate"><span class="pre">ELF</span></code>. This
|
|||
|
program snippet confirms that <code class="docutils literal notranslate"><span class="pre">bash</span></code> on Linux is a valid ELF file. (It should be.)</p>
|
|||
|
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl3-6"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 3.6:</span>
|
|||
|
<span class="cm"> Read the first bytes of the bash executable to confirm it is ELF format</span>
|
|||
|
<span class="cm"> */</span>
|
|||
|
|
|||
|
<span class="cm">/* Open the bash ELF executable file on Linux */</span>
|
|||
|
<span class="kt">int</span> <span class="n">fd</span> <span class="o">=</span> <span class="n">open</span> <span class="p">(</span><span class="s">"/bin/bash"</span><span class="p">,</span> <span class="n">O_RDONLY</span><span class="p">);</span>
|
|||
|
<span class="n">assert</span> <span class="p">(</span><span class="n">fd</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
|
|||
|
|
|||
|
<span class="cm">/* Get information about the file, including size */</span>
|
|||
|
<span class="k">struct</span> <span class="n">stat</span> <span class="n">file_info</span><span class="p">;</span>
|
|||
|
<span class="n">assert</span> <span class="p">(</span><span class="n">fstat</span> <span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="o">&</span><span class="n">file_info</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">/* Create a private, read-only memory mapping */</span>
|
|||
|
<span class="kt">char</span> <span class="o">*</span><span class="n">mmap_addr</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="n">file_info</span><span class="p">.</span><span class="n">st_size</span><span class="p">,</span> <span class="n">PROT_READ</span><span class="p">,</span> <span class="n">MAP_PRIVATE</span><span class="p">,</span> <span class="n">fd</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">mmap_addr</span> <span class="o">!=</span> <span class="n">MAP_FAILED</span><span class="p">);</span>
|
|||
|
|
|||
|
<span class="cm">/* ELF specification:</span>
|
|||
|
<span class="cm"> Bytes 1 - 3 of the file must be 'E', 'L', 'F' */</span>
|
|||
|
<span class="n">assert</span> <span class="p">(</span><span class="n">mmap_addr</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="sc">'E'</span><span class="p">);</span>
|
|||
|
<span class="n">assert</span> <span class="p">(</span><span class="n">mmap_addr</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="sc">'L'</span><span class="p">);</span>
|
|||
|
<span class="n">assert</span> <span class="p">(</span><span class="n">mmap_addr</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">==</span> <span class="sc">'F'</span><span class="p">);</span>
|
|||
|
|
|||
|
<span class="cm">/* Unmap the file and close it */</span>
|
|||
|
<span class="n">munmap</span> <span class="p">(</span><span class="n">mmap_addr</span><span class="p">,</span> <span class="n">file_info</span><span class="p">.</span><span class="n">st_size</span><span class="p">);</span>
|
|||
|
<span class="n">close</span> <span class="p">(</span><span class="n">fd</span><span class="p">);</span>
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
<div class="figure mb-2 align-right" id="id3" style="width: 40%">
|
|||
|
<span id="ipcmap"></span><a class="reference internal image-reference" href="_images/CSF-Images.3.4.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Memory-mapped files use provide direct access to contents" src="_images/CSF-Images.3.4.png" style="width: 90%;" /></a>
|
|||
|
<p class="caption align-center px-3"><span class="caption-text"> Figure 3.4.2: Memory-mapped files use provide direct access to contents</span></p>
|
|||
|
</div>
|
|||
|
<p><a href="MMap.html#ipcmap">Figure 3.4.2</a> illustrates the structure of the memory-mapped file in <a class="reference external" href="MMap.html#cl3-6">Code Listing
|
|||
|
3.6</a>. The file’s original contents are stored on the hard drive. When the file is mapped into memory,
|
|||
|
the process has a region of memory that corresponds to the exact structure of the file, creating the
|
|||
|
appearance that the file’s contents have been copied into memory. The call to <code class="docutils literal notranslate"><span class="pre">mmap()</span></code> returns a
|
|||
|
pointer to this region, which can be accessed as an array of bytes.</p>
|
|||
|
<table class="docutils footnote" frame="void" id="f17" rules="none">
|
|||
|
<colgroup><col class="label" /><col /></colgroup>
|
|||
|
<tbody valign="top">
|
|||
|
<tr><td class="label"><a class="fn-backref" href="MMap.html#id1">[1]</a></td><td>Bypassing the kernel’s buffer cache can also be a disadvantage if other processes access
|
|||
|
the file using the traditional <code class="docutils literal notranslate"><span class="pre">read()</span></code> function. Specifically, both processes (one with the
|
|||
|
memory map and one without) will cause the data to be copied from disk into memory. Making the
|
|||
|
second transfer from disk into memory is significantly slower than making a duplicate copy from the
|
|||
|
buffer cache (which is in memory). Consequently, both processes would take a performance hit for
|
|||
|
loading the file from disk, even though the process using the memory-mapped file would experience
|
|||
|
slightly less impact.</td></tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
<div
|
|||
|
id="IPCMmapSumm"
|
|||
|
class="embedContainer"
|
|||
|
data-exer-name="IPCMmapSumm"
|
|||
|
data-long-name="IPC memory-mapped file questions"
|
|||
|
data-short-name="IPCMmapSumm"
|
|||
|
data-frame-src="../../../Exercises/IPC/IPCMmapSumm.html?selfLoggingEnabled=false&localMode=true&module=MMap&JXOP-debug=true&JOP-lang=en&JXOP-code=java"
|
|||
|
data-frame-width="950"
|
|||
|
data-frame-height="550"
|
|||
|
data-external="false"
|
|||
|
data-points="1.0"
|
|||
|
data-required="True"
|
|||
|
data-showhide="show"
|
|||
|
data-threshold="3"
|
|||
|
data-type="ka"
|
|||
|
data-exer-id="">
|
|||
|
|
|||
|
<div class="center">
|
|||
|
<div id="IPCMmapSumm_iframe"></div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="container">
|
|||
|
|
|||
|
<div class="mt-4 container center">
|
|||
|
«  <a id="prevmod1" href="Pipes.html">3.3. Pipes and FIFOs</a>
|
|||
|
  ::  
|
|||
|
<a class="uplink" href="index.html">Contents</a>
|
|||
|
  ::  
|
|||
|
<a id="nextmod1" href="POSIXvSysV.html">3.5. POSIX vs. System V IPC</a>  »
|
|||
|
</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>
|