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

573 lines
37 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>6.2. Processes vs. Threads &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="3. Race Conditions and Critical Sections" href="RaceConditions.html" />
<link rel="prev" title="1. Concurrency with Multithreading" href="ThreadsOverview.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="ProcVThreads.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="ProcVThreads.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/ProcVThreads.rst"
target="_blank" rel="nofollow">Show Source</a></li>
</ul>
</nav>
<div class="container center">
«&#160;&#160;<a id="prevmod" href="ThreadsOverview.html">6.1. Concurrency with Multithreading</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod" href="RaceConditions.html">6.3. Race Conditions and Critical Sections</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 = "ProcVThreads";ODSA.SETTINGS.MODULE_LONG_NAME = "Processes vs. Threads";ODSA.SETTINGS.MODULE_CHAPTER = "Concurrency with Multithreading"; ODSA.SETTINGS.BUILD_DATE = "2021-06-14 17:15:25"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="processes-vs-threads">
<h1>6.2. Processes vs. Threads<a class="headerlink" href="ProcVThreads.html#processes-vs-threads" title="Permalink to this headline"></a></h1>
<p>Recall from <a class="reference external" href="ProcessesOverview.html">Processes and OS Basics</a> that a <a class="reference internal" href="Glossary.html#term-process"><span class="xref std std-term">process</span></a>
is fundamentally defined by having a unique virtual memory space. The process
contains a code segment that consists of the executable machine-language
instructions, while the statically allocated global variables are stored in the
data segment. The heap and stack segments contain the dynamically allocated data
and local variables for this execution of the program.</p>
<p>Every process begins by executing the instructions contained in <code class="docutils literal notranslate"><span class="pre">main()</span></code>. The
<code class="docutils literal notranslate"><span class="pre">%pc</span></code> register defines the flow of the code by pointing to the next
instruction to be executed. The call instruction can modify the control flow by
jumping to other functions. When this happens, the return address (and other
related information) is placed on the stack to maintain the programs logical
flow. This single, logical sequence of executing instructions within a process
is known as a <em>thread of execution</em>, which we typically just call a <a class="reference internal" href="Glossary.html#term-thread"><span class="xref std std-term">thread</span></a>.</p>
<div class="section" id="multithreading">
<h2>6.2.1. Multithreading<a class="headerlink" href="ProcVThreads.html#multithreading" title="Permalink to this headline"></a></h2>
<p><a class="reference internal" href="Glossary.html#term-multithreading"><span class="xref std std-term">Multithreaded</span></a> processes have multiple threads that perform tasks
concurrently. Just like the thread that runs the code in <code class="docutils literal notranslate"><span class="pre">main()</span></code>, additional
threads each use a function as an entry point. To maintain the logical flow of
these additional threads, each thread is assigned a separate stack. However, all
of the other segments of memory, including the code, global data, heap, and
kernel, are shared.</p>
<p>Another way to consider the relationship between threads and processes is to
separate the system functions of <a class="reference internal" href="Glossary.html#term-scheduling"><span class="xref std std-term">scheduling</span></a> and <em>resource
ownership</em>. Switching from one thread to another would change the system from
working toward one computational goal to working toward another. This means that
the purpose of switching between threads is to create a schedule that controls
when each thread is running on the CPU.</p>
<p>On the other hand, processes act as containers for resource ownership. As the
process runs, it may request access to files stored on the disk, open network
connections, or request the creation of a new window on the desktop. All of
these resources are allocated to the process, not individual threads.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-1"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.1:</span>
<span class="cm"> Structure of a simple multithreaded program framework</span>
<span class="cm"> */</span>
<span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp"></span>
<span class="cm">/* Include thread libraries */</span>
<span class="kt">int</span> <span class="n">number</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="kt">void</span> <span class="o">*</span>
<span class="nf">thread_A</span> <span class="p">(</span><span class="kt">void</span><span class="o">*</span> <span class="n">args</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;A: %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">x</span> <span class="o">+</span> <span class="n">number</span><span class="p">);</span>
<span class="cm">/* Exit thread */</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="o">*</span>
<span class="nf">thread_B</span> <span class="p">(</span><span class="kt">void</span><span class="o">*</span> <span class="n">args</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;B: %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">y</span> <span class="o">+</span> <span class="n">number</span><span class="p">);</span>
<span class="cm">/* Exit thread */</span>
<span class="p">}</span>
<span class="kt">int</span>
<span class="nf">main</span> <span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">**</span> <span class="n">argv</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* Create thread A */</span>
<span class="cm">/* Create thread B */</span>
<span class="cm">/* Wait for threads to finish */</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p><a class="reference external" href="ProcVThreads.html#cl6-1">Code Listing 6.1</a> shows the structure of a simple program that creates two
threads that run concurrently. For now, comments are used to indicate where the
thread management code would be written. Thread A declares a local variable
<code class="docutils literal notranslate"><span class="pre">x</span></code> and prints out the message A: 8, which is the sum of the value of <code class="docutils literal notranslate"><span class="pre">x</span></code>
(5) and the global variable <code class="docutils literal notranslate"><span class="pre">number</span></code> (3). Thread B declares <code class="docutils literal notranslate"><span class="pre">y</span></code> and prints
out B: 5, for similar reasons. One observation about this sample is that the
code for the threads looks like normal functions in a typical program. The
difference only becomes apparent when we run the program.</p>
<p>When the program is run, the scheduling that controls when the threads run is
<a class="reference internal" href="Glossary.html#term-nondeterminism"><span class="xref std std-term">nondeterministic</span></a> from the programmers perspective. By looking at the
code, we can conclude that line 13 runs before line 14, just like line 21 runs
before line 22. However, we cannot predict the ordering between line 13 and line
21. This choice is made at run-time and is controlled by the kernel. When
looking at source code for multithreaded programs, we assume the lines of code
are <a class="reference internal" href="Glossary.html#term-interleaved"><span class="xref std std-term">interleaved</span></a>, meaning that the kernel can switch back and forth
whenever it chooses to do so.</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-Example.png"><img alt="Decorative example icon" src="_images/CSF-Images-Example.png" style="width: 100%;" /></a>
</div>
<p class="topic-title first pt-2 mb-1">Example 6.2.1 </p><hr class="mt-1" />
<p><a class="reference external" href="ProcVThreads.html#tbl6-1">Table 6.1</a> shows three of the possible interleavings of <a class="reference external" href="ProcVThreads.html#cl6-1">Code Listing 6.1</a>. In each
of these cases, the indentation is used to indicate which thread performs an
action (thread A is not indented and thread B is). In interleaving 1, thread A
runs to completion before thread B starts. In interleaving 2, thread B sets the
value of y before thread A prints its message. <strong>Note that this timing is not
observed without a debugger, since setting y produces no visible result.</strong>
Finally, in interleaving 3, thread Bs print statement occurs before thread As.</p>
<center>
<div class="col-md-10">
<table class="table table-bordered">
<thead class="jmu-dark-purple-bg text-light">
<tr>
<th class="py-0 center" style="width: 33%">Interleaving 1</th>
<th class="py-0 center" style="width: 33%">Interleaving 2</th>
<th class="py-0 center" style="width: 33%">Interleaving 3</th>
</tr>
</thead>
<tbody class="bg-white">
<tr>
<td class="py-0"><code>x = 5<br />print "A:8"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y = 2<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print "B:7"</code></td>
<td class="py-0"><code>x = 5<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y = 2<br />print "A:8"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print "B:7"</code></td>
<td class="py-0"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y = 2<br />x = 5<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print "B:7"<br />print "A:8"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-8 center">
Table 6.1: Three possible interleavings of Code Listing 6.1
</div>
<br /></div>
<p>More interleavings are possible than those shown in <a class="reference external" href="ProcVThreads.html#tbl6-1">Table 6.1</a>. The
only requirement is that the order of instructions <strong>within a single thread</strong>
must match the order specified in the code. The selection of which thread has an
instruction run is seemingly randomized.</p>
</div>
<div class="section" id="advantages-and-disadvantages-of-threads">
<h2>6.2.2. Advantages and Disadvantages of Threads<a class="headerlink" href="ProcVThreads.html#advantages-and-disadvantages-of-threads" title="Permalink to this headline"></a></h2>
<p>Using multiple threads offers a number of advantages over creating an
application from multiple processes. First, using multiple threads helps
programmers build modularity into their code more effectively. Complex software,
especially the types of applications built with object-oriented programming,
typically involves modular components that interact with each other. Oftentimes,
the program can run more efficiently if these components can run concurrently
without performing context switches. Threads provide a foundation for this
programming goal.</p>
<p>One common example of using threads for different purposes is an interactive
graphical user interface. Application programmers build in keyboard or mouse
listeners that are responsible for detecting and responding to key presses,
mouse clicks, and other such events. These types of event listeners are simply
concurrent threads within the process. By implementing the listener behavior in
a separate thread, the programmer can simplify the structure of the program.</p>
<p>Threads also require significantly less overhead for switching and for
communicating. A process context switch requires changing the systems current
view of virtual memory, which is a time-consuming operation. Switching from one
thread to another is a lot faster. For two processes to exchange data, they have
to initiate <a class="reference internal" href="Glossary.html#term-interprocess-communication"><span class="xref std std-term">interprocess communication (IPC)</span></a>, which requires asking the kernel for help. IPC generally
involves performing at least one context switch. Since all threads in a process
share the heap, data, and code, there is no need to get the kernel involved. The
threads can communicate directly by reading and writing global variables.</p>
<p>At the same time, the lack of isolation between threads in a single process can
also lead to some disadvantages. If one thread crashes due to a segmentation
fault or other error, all other threads and the entire process are killed. This
situation can lead to data and system corruption if the other threads were in
the middle of some important task.</p>
<p>As an example, assume that the application is a server program with one thread
responsible for logging all requests and a separate thread for handling the
requests. If the request handler thread crashes before the logging thread has a
chance to write the request to its log file, there would be no record of the
request. The system administrators left to determine what went wrong would have
no information about the request, so they may waste a lot of time validating
other requests that were all good.</p>
<p>The lack of isolation between threads also creates a new type of programming
bugs called <a class="reference internal" href="Glossary.html#term-race-condition"><span class="xref std std-term">race conditions</span></a>. In a race condition, the
behavior of the program depends on the timing of the thread scheduling. One
example of a race condition is when two threads both try to change the value of
a global variable. The final value of the global variable would depend on which
thread set the value last.</p>
</div>
<div class="section" id="thread-models">
<h2>6.2.3. Thread Models<a class="headerlink" href="ProcVThreads.html#thread-models" title="Permalink to this headline"></a></h2>
<p>Throughout this chapter, we will be focusing on the POSIX thread model, which is
independent of language and OS (though mostly associated with UNIX-like OS). The
POSIX specification defines a thread as a <em>single flow of control within a
process.</em> Based on this definition, all threads within a process exist in a
single address space; as such, all threads in a process can access anything
stored in memory if the address can be determined. On the other hand, each
thread has a unique copy of certain pieces of data that are required for
execution; these unique copies include the <code class="docutils literal notranslate"><span class="pre">errno</span></code> variable (used for
detecting errors that occur in C standard library functions), general purpose
registers, and a stack pointer. <a class="reference external" href="ProcVThreads.html#tbl6-2">Table 6.2</a> summarizes what the POSIX
specificat declares is unique per thread and what is accessible to all threads.</p>
<center>
<div class="col-md-10 center">
<table class="table table-bordered">
<thead class="jmu-dark-purple-bg text-light">
<tr>
<th class="py-0 center">Unique per thread</th>
<th class="py-0 center">Accessible by all threads in process</th>
</tr>
</thead>
<tbody class="text-left">
<tr>
<td class="py-0">
<ul>
<li>Thread ID</li>
<li>Scheduling priority and policies</li>
<li><code>errno</code> value</li>
<li>Floating point environment</li>
<li>Thread-specific key/value bindings</li>
<li>Resources required for control flow</li>
</ul>
</td>
<td class="py-0">
<ul>
<li>Static variables</li>
<li>Storage obtained by <code>malloc()</code></li>
<li>Directly addressable storage</li>
<li>Automatic variables</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-10 center">
Table 6.2: Data that is unique to or shared between POSIX threads
</div>
</center>
<br /><p>In typical implementations, scheduling of POSIX threads is typically performed
by the kernel. This approach allows the kernel to make scheduling decisions
consistently across processes, while also making context switches between
threads efficient (as the virtual memory image does not change). The POSIX model
is not the only way to structure and organize threads. There are other models
that have been used for multithreading in a variety of systems.</p>
<p>Early versions of Java used the <a class="reference internal" href="Glossary.html#term-green-threads"><span class="xref std std-term">Green threads</span></a> model (named for the Green
Team inside the Sun Microsystems that implemented the library). In this model,
the Java virtual machine (JVM), which ran as a single process, is responsible
for scheduling between threads in an application. The kernel underlying the JVM
had no awareness of the presence of multiple threads. An advantage of this
approach is that switching between threads is efficient, as there are no system
calls that require the intervention of the kernel. However, all threads had to
subdivide the processs given CPU time; as the number of threads increased,
performance would dramatically decrease, as each thread would get less and less CPU time.</p>
<p>Solaris and other forms of System V UNIX adopted a model known as
<a class="reference internal" href="Glossary.html#term-light-weight-process"><span class="xref std std-term">light-weight processes (LWPs)</span></a>. In this model,
multiple LWPs within a single process execute on top of a single kernel thread.
Like the Green threads model, scheduling between LWPs is handled by a user-mode
thread library rather than the kernel. However, unlike Green threads, the LWP
model allows a single process to run on top of multiple kernel threads. This
approach creates a many-to-many relationship between user- and kernel-mode
threads. Consequently, processes with several LWPs could distribute their
execution time across multiple kernel threads for more CPU time.</p>
<p>Windows and the .NET framework use a <a class="reference internal" href="Glossary.html#term-fiber"><span class="xref std std-term">fiber</span></a> model, which is similar to
the POSIX model. Like a POSIX thread, fibers share a single address space and
each fiber is mapped to a single kernel thread. The primary difference is that
fibers within a single process use cooperative multitasking. This approach
offers a significant advantage for ensuring safe access to resources shared
between the threads, as the fibers have greater control over when switches
occur.</p>
<p><a href="ProcVThreads.html#thrmodel">Figure 6.2.2</a> summarizes how the four threading models map user
threads to kernel threads. In all cases but Green threads, we assume that the
process consists of three kernel threads that can be scheduled independently.
The POSIX threads and fibers form a 1:1 model from user threads to kernel
threads, with the primary difference being the intervention of the fiber
scheduler. The Green threads model forms an N:1 relationship, as the kernel is
not aware of the multiple threads running on top of the JVM. The LWP model is
described as M:N because there is no direct link between the number of user and
kernel threads. For each of the N kernel threads, there is a virtual CPU, and
the LWP library dynamically maps the M user threads to these virtual CPUs
according to its own scheduling policies.</p>
<div class="figure mb-2 align-center" id="id3" style="width: 100%">
<span id="thrmodel"></span><a class="reference internal image-reference" href="_images/CSF-Images.6.1.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Mapping models for POSIX, Green threads, fibers, and lightweight processes" src="_images/CSF-Images.6.1.png" style="width: 90%;" /></a>
<p class="caption align-center px-3"><span class="caption-text"> Figure 6.2.2: Mapping models for POSIX, Green threads, fibers, and lightweight processes</span></p>
</div>
<div
id="ProcVThreadsSumm"
class="embedContainer"
data-exer-name="ProcVThreadsSumm"
data-long-name="Threads vs. processes questions"
data-short-name="ProcVThreadsSumm"
data-frame-src="../../../Exercises/Threads/ProcVThreadsSumm.html?selfLoggingEnabled=false&amp;localMode=true&amp;module=ProcVThreads&amp;JXOP-debug=true&amp;JOP-lang=en&amp;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="4"
data-type="ka"
data-exer-id="">
<div class="center">
<div id="ProcVThreadsSumm_iframe"></div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="mt-4 container center">
«&#160;&#160;<a id="prevmod1" href="ThreadsOverview.html">6.1. Concurrency with Multithreading</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod1" href="RaceConditions.html">6.3. Race Conditions and Critical Sections</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>