1
0
Fork 0
cl-sites/w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/html/ImplicitThreads.html
2025-01-28 10:11:14 +01:00

763 lines
No EOL
48 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>6.6. Implicit Threading and Language-based 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="7. Extended Example: Keyboard Input Listener" href="Extended6Input.html" />
<link rel="prev" title="5. Thread Arguments and Return Values" href="ThreadArgs.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="ImplicitThreads.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="ImplicitThreads.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/ImplicitThreads.rst"
target="_blank" rel="nofollow">Show Source</a></li>
</ul>
</nav>
<div class="container center">
«&#160;&#160;<a id="prevmod" href="ThreadArgs.html">6.5. Thread Arguments and Return Values</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod" href="Extended6Input.html">6.7. Extended Example: Keyboard Input Listener</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 = "ImplicitThreads";ODSA.SETTINGS.MODULE_LONG_NAME = "Implicit Threading and Language-based Threads";ODSA.SETTINGS.MODULE_CHAPTER = "Concurrency with Multithreading"; 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="implicit-threading-and-language-based-threads">
<h1>6.6. Implicit Threading and Language-based Threads<a class="headerlink" href="ImplicitThreads.html#implicit-threading-and-language-based-threads" title="Permalink to this headline"></a></h1>
<p>The POSIX thread library is a powerful and robust mechanism for concurrent
systems programming. However, the library places a significant burden on the
programmer to ensure that the implementation avoids race conditions and other
bugs. In <a class="reference external" href="SynchProblemsOverview.html">Synchronization Problems</a>, we will
examine common patterns that emerge in these types of programs and how to avoid subtle errors.</p>
<p>Since threads were first introduced, language designers have explored a number
of techniques that reduce the complexity and responsibility of managing threads.
This section will examine three different approaches for making multithreading
easier. The first approach is a general style called <a class="reference internal" href="Glossary.html#term-implicit-threading"><span class="xref std std-term">implicit threading</span></a>
which aims to hide the management of threads as much as possible. The second
approach is to treat threads as objects in languages like Java and Python. The
third (and most modern) approach is to design the language around the concept of
concurrency as a fundamental feature.</p>
<div class="section" id="implicit-threading-with-openmp">
<h2>6.6.1. Implicit Threading with OpenMP<a class="headerlink" href="ImplicitThreads.html#implicit-threading-with-openmp" title="Permalink to this headline"></a></h2>
<p>Implicit threading is the use of libraries or other language support to hide the
management of threads. In the context of C, the most common implicit threading
library is <a class="reference internal" href="Glossary.html#term-openmp"><span class="xref std std-term">OpenMP</span></a>. OpenMP uses the <code class="docutils literal notranslate"><span class="pre">#pragma</span></code> compiler directive to
detect and insert additional library code at compile time. As an example,
consider the prime number calculator from the Extended Examples.
<a class="reference external" href="ImplicitThreads.html#cl6-17">Code Listing 6.17</a> shows the OpenMP equivalent.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-17"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.17:</span>
<span class="cm"> OpenMP can make some multithreading trivial to implement</span>
<span class="cm"> */</span>
<span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;stdbool.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;omp.h&gt;</span><span class="cp"></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">/* Set up the overall algorithm parameters */</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">end</span> <span class="o">=</span> <span class="mi">100000000L</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">iter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="cm">/* OpenMP parallel for-loop with reduction on count. Each thread</span>
<span class="cm"> will have its own count, but they&#39;ll be combined when all</span>
<span class="cm"> threads are done. */</span>
<span class="cp">#pragma omp parallel for default(shared) private(iter) \</span>
<span class="cp"> reduction(+:count)</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">alue</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="n">value</span> <span class="o">&lt;</span> <span class="n">end</span><span class="p">;</span> <span class="n">value</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">bool</span> <span class="n">is_prime</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">iter</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="n">iter</span> <span class="o">*</span> <span class="n">iter</span> <span class="o">&lt;=</span> <span class="n">value</span> <span class="o">&amp;&amp;</span> <span class="n">is_prime</span><span class="p">;</span> <span class="n">iter</span><span class="o">++</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">value</span> <span class="o">%</span> <span class="n">iter</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">is_prime</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">is_prime</span><span class="p">)</span>
<span class="n">count</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Total number of primes less than %ld: %ld</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">end</span><span class="p">,</span>
<span class="n">count</span><span class="p">);</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>With implicit threading, the focus of the programmer is on writing the algorithm
rather than the multithreading. The OpenMP library itself takes care of managing
the threads. Specifically, the <code class="docutils literal notranslate"><span class="pre">#pragma</span></code> line indicates that OpenMP (<code class="docutils literal notranslate"><span class="pre">omp</span></code>)
should parallelize a for-loop (<code class="docutils literal notranslate"><span class="pre">parallel</span> <span class="pre">for</span></code>) with some constraints on the
variables. The OpenMP implementation on that system will then inject code to
perform the thread creation and join.</p>
<p>OpenMP in C is built on top of the pthread library. As such, any code that can
be written using OpenMP can be converted into a more verbose pthread equivalent.
However, the disadvantage of OpenMP is that it only works for certain types of
tasks. There are many types of programs, such as the keyboard listener example,
that can be implemented in pthreads but not OpenMP.</p>
</div>
<div class="section" id="threads-as-objects">
<h2>6.6.2. Threads as Objects<a class="headerlink" href="ImplicitThreads.html#threads-as-objects" title="Permalink to this headline"></a></h2>
<p>In other languages, traditional object-oriented languages provide explicit
multithreading support with threads as objects. In these types of languages,
classes are written to either extend a thread class or implement a corresponding
interface. This style resembles the pthread approach, as the code is written
with explicit thread management. However, the encapsulation of data within the
classes and additional synchronization features simplify the task.</p>
<div class="section" id="java-threads">
<h3>6.6.2.1. Java Threads<a class="headerlink" href="ImplicitThreads.html#java-threads" title="Permalink to this headline"></a></h3>
<p>Java provides both a <code class="docutils literal notranslate"><span class="pre">Thread</span></code> class and a <code class="docutils literal notranslate"><span class="pre">Runnable</span></code> interface that can be
used, as shown in <a class="reference external" href="ImplicitThreads.html#cl6-18">Code Listing 6.18</a>. Both require implementing a
public void <code class="docutils literal notranslate"><span class="pre">run()</span></code> method that defines the entry point of the thread. Once an
instance of the object is allocated, the thread can be started by invoking the
<code class="docutils literal notranslate"><span class="pre">start()</span></code> method on it. As with pthreads, starting the thread is asynchronous,
so the timing of the execution is nondeterministic.</p>
<div class="highlight-java border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-18"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.18:</span>
<span class="cm"> Java offers both a class and an interface to support threads as objects</span>
<span class="cm"> */</span>
<span class="kd">class</span> <span class="nc">ThreadExtender</span> <span class="kd">extends</span> <span class="n">Thread</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">()</span> <span class="o">{</span>
<span class="cm">/* Implement code here */</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">RunImplement</span> <span class="kd">implements</span> <span class="n">Runnable</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">()</span> <span class="o">{</span>
<span class="cm">/* Implement code here */</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span> <span class="n">args</span><span class="o">[])</span> <span class="o">{</span>
<span class="cm">/* Instantiate the ThreadExtender and start it */</span>
<span class="n">ThreadExtender</span> <span class="n">te</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ThreadExtender</span><span class="o">();</span>
<span class="n">te</span><span class="o">.</span><span class="na">start</span><span class="o">();</span>
<span class="cm">/* Instantiate the Runnable version and start it */</span>
<span class="n">RunImplement</span> <span class="n">ri</span> <span class="o">=</span> <span class="k">new</span> <span class="n">RunImplement</span><span class="o">();</span>
<span class="n">Thread</span> <span class="n">t</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Thread</span><span class="o">(</span><span class="n">ri</span><span class="o">);</span>
<span class="n">t</span><span class="o">.</span><span class="na">start</span><span class="o">();</span>
<span class="cm">/* Join the threads */</span>
<span class="n">te</span><span class="o">.</span><span class="na">join</span><span class="o">();</span>
<span class="n">j</span><span class="o">.</span><span class="na">join</span><span class="o">();</span>
<span class="o">}</span>
</pre></div>
</td></tr></table></div>
</div>
<div class="section" id="python-threads">
<h3>6.6.2.2. Python Threads<a class="headerlink" href="ImplicitThreads.html#python-threads" title="Permalink to this headline"></a></h3>
<p><a class="reference external" href="ImplicitThreads.html#cl6-19">Code Listing 6.19</a> demonstrates two mechanisms for multithreading in
Python. One approach is similar to the pthread style, where a function name is
passed to a library method <code class="docutils literal notranslate"><span class="pre">thread.start_new_thread()</span></code>. This approach is very
limited and lacks the ability to join or terminate the thread after it starts. A
more flexible technique is to use the threading module to define a class that
extends threading. Similar to the Java approach, the class must have a <code class="docutils literal notranslate"><span class="pre">run()</span></code>
method that provides the threads entry point. Once an object is instantiated
from this class, it can be explicitly started and joined later.</p>
<div class="highlight-python border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-19"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="c1"># Code Listing 6.19:</span>
<span class="c1"># Python offers a pthread-like interface and an object-oriented module for threading */</span>
<span class="c1">#!/usr/bin/python</span>
<span class="kn">import</span> <span class="nn">thread</span>
<span class="kn">import</span> <span class="nn">threading</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="c1"># Low-level procedural approach with the thread module</span>
<span class="k">def</span> <span class="nf">proc_thread</span> <span class="p">(</span><span class="n">name</span><span class="p">):</span>
<span class="c1"># thread code here</span>
<span class="k">print</span> <span class="s2">&quot;Ran thread &quot;</span> <span class="o">+</span> <span class="n">name</span>
<span class="c1"># Use thread module to create and start the thread</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">thread</span><span class="o">.</span><span class="n">start_new_thread</span><span class="p">(</span><span class="n">proc_thread</span><span class="p">,</span> <span class="p">(</span><span class="s2">&quot;First Thread&quot;</span><span class="p">,</span> <span class="p">))</span>
<span class="k">except</span><span class="p">:</span>
<span class="k">print</span> <span class="s2">&quot;Failed to start thread&quot;</span>
<span class="c1"># OOP approach using the threading module</span>
<span class="k">class</span> <span class="nc">ObjThread</span> <span class="p">(</span><span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># Thread entry point here</span>
<span class="k">print</span> <span class="s2">&quot;Running object thread &quot;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
<span class="c1"># Create an instance of the object to start and join</span>
<span class="n">threadObj</span> <span class="o">=</span> <span class="n">ObjThread</span><span class="p">(</span><span class="s2">&quot;Second Thread&quot;</span><span class="p">)</span>
<span class="n">threadObj</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">threadObj</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
<span class="c1"># Delay to make sure both run</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="concurrency-as-language-design">
<h2>6.6.3. Concurrency as Language Design<a class="headerlink" href="ImplicitThreads.html#concurrency-as-language-design" title="Permalink to this headline"></a></h2>
<p>Languages such as C, Java, and Python were all designed before <a class="reference internal" href="Glossary.html#term-multicore"><span class="xref std std-term">multicore</span></a>
architectures rose to prominence in the early 2000s. As such, multithreading
support in these languages was added as a supplement to the language, rather
than a core feature. These languages were originally designed for a
uniprocessing procedural or object-oriented paradigm. As a result, the memory
models that underlie these languages are not adequate to prevent race
conditions. The multithreading libraries had to provide additional features that
allowed programmers to synchronize access to shared data. Or, put another way,
programmers were forced to do extra work to make their programs work correctly.</p>
<p>Newer programming languages have avoided this problem by building assumptions of
concurrent execution directly into the language design itself. For instance, Go
combines a trivial implicit threading technique (goroutines) with channels, a
well-defined form of message-passing communication. Rust adopts an explicit
threading approach similar to pthreads. However, Rust has very strong memory
protections that require no additional work by the programmer.</p>
<div class="section" id="goroutines">
<h3>6.6.3.1. Goroutines<a class="headerlink" href="ImplicitThreads.html#goroutines" title="Permalink to this headline"></a></h3>
<p>The Go language includes a trivial mechanism for implicit threading: place the
keyword go before a function call. In <a class="reference external" href="ImplicitThreads.html#cl6-20">Code Listing 6.20</a>, the line
go <code class="docutils literal notranslate"><span class="pre">keyboard_listener(messages)</span></code> launches a new thread that will execute the
keyboard listener function. The new thread is passed a connection to a
message-passing <em>channel</em>. Then, the main thread calls
<code class="docutils literal notranslate"><span class="pre">success</span> <span class="pre">:=</span> <span class="pre">&lt;-messages</span></code>, which performs a blocking read on the channel. Once
the user has entered the correct guess of 7, the keyboard listener thread writes
to the channel, allowing the main thread to progress.</p>
<p>Channels and <a class="reference internal" href="Glossary.html#term-goroutine"><span class="xref std std-term">goroutines</span></a> are core parts of the Go language,
which was designed under the assumption that most programs would be
multithreaded. This design choice streamlines the development model, allowing
the language itself to bear the responsibility for managing the threads and scheduling.</p>
<div class="highlight-go border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-20"><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
42
43
44
45
46
47
48
49
50
51
52
53</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.20:</span>
<span class="cm"> Go provides built-in concurrency techniques with goroutines and channels for communication</span>
<span class="cm">*/</span>
<span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">&quot;bufio&quot;</span>
<span class="s">&quot;fmt&quot;</span>
<span class="s">&quot;os&quot;</span>
<span class="s">&quot;strconv&quot;</span>
<span class="s">&quot;strings&quot;</span>
<span class="p">)</span>
<span class="cm">/* Main program entry point */</span>
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
<span class="cm">/* Create a channel for communication */</span>
<span class="nx">messages</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">string</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Print</span><span class="p">(</span><span class="s">&quot;Guess a number between 1 and 10: &quot;</span><span class="p">)</span>
<span class="cm">/* Start keyboard listener as a goroutine with the channel */</span>
<span class="k">go</span> <span class="nx">keyboard_listener</span><span class="p">(</span><span class="nx">messages</span><span class="p">)</span>
<span class="cm">/* Wait until there is data in the channel */</span>
<span class="nx">success</span> <span class="o">:=</span> <span class="o">&lt;-</span><span class="nx">messages</span>
<span class="k">if</span> <span class="nx">success</span> <span class="o">==</span> <span class="s">&quot;true&quot;</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;You must have guess 7.&quot;</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="cm">/* Define the keyboard listener thread with channel back to main */</span>
<span class="kd">func</span> <span class="nx">keyboard_listener</span><span class="p">(</span><span class="nx">messages</span> <span class="kd">chan</span> <span class="kt">string</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">stdin</span> <span class="o">:=</span> <span class="nx">bufio</span><span class="p">.</span><span class="nx">NewReader</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdin</span><span class="p">)</span>
<span class="cm">/* Loop forever, reading keyboard input */</span>
<span class="k">for</span> <span class="p">{</span>
<span class="nx">text</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">stdin</span><span class="p">.</span><span class="nx">ReadString</span><span class="p">(</span><span class="sc">&#39;\n&#39;</span><span class="p">)</span>
<span class="cm">/* Try to convert the input text to an int 7 */</span>
<span class="nx">value</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span>
<span class="nx">strconv</span><span class="p">.</span><span class="nx">ParseInt</span><span class="p">(</span><span class="nx">strings</span><span class="p">.</span><span class="nx">Trim</span><span class="p">(</span><span class="nx">text</span><span class="p">,</span> <span class="s">&quot;\n&quot;</span><span class="p">),</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">32</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">==</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="k">if</span> <span class="nx">value</span> <span class="o">==</span> <span class="mi">7</span> <span class="p">{</span>
<span class="cm">/* Success. Send a message back through</span>
<span class="cm"> the channel and exit */</span>
<span class="nx">messages</span> <span class="o">&lt;-</span> <span class="s">&quot;true&quot;</span>
<span class="k">return</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Print</span><span class="p">(</span><span class="s">&quot;Wrong. Try again. &quot;</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<div class="section" id="rust-concurrency">
<h3>6.6.3.2. Rust Concurrency<a class="headerlink" href="ImplicitThreads.html#rust-concurrency" title="Permalink to this headline"></a></h3>
<p>Rust is another language that has been created in recent years, with concurrency
as a central design feature. <a class="reference external" href="ImplicitThreads.html#cl6-21">Code Listing 6.21</a> illustrates the use
of <code class="docutils literal notranslate"><span class="pre">thread::spawn()</span></code> to create a new thread, which can later be joined by
invoking <code class="docutils literal notranslate"><span class="pre">join()</span></code> on it. The argument to <code class="docutils literal notranslate"><span class="pre">thread::spawn()</span></code> beginning at the
<code class="docutils literal notranslate"><span class="pre">||</span></code> is known as a closure, which can be thought of as an anonymous function.
That is, the child thread here will print the value of <code class="docutils literal notranslate"><span class="pre">x</span></code>.</p>
<div class="highlight-rust border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-21"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.21:</span>
<span class="cm"> Rust threads can be created with anonymous functions known as closure</span>
<span class="cm"> */</span><span class="w"></span>
<span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">thread</span><span class="p">;</span><span class="w"></span>
<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="cm">/* Initialize a mutable variable x to 10 */</span><span class="w"></span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">10</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="cm">/* Spawn a new thread */</span><span class="w"></span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">child_thread</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">thread</span>::<span class="n">spawn</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>
<span class="w"> </span><span class="cm">/* Make the thread sleep for one second, then print x */</span><span class="w"></span>
<span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;x = {}&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"></span>
<span class="w"> </span><span class="p">});</span><span class="w"></span>
<span class="w"> </span><span class="cm">/* Change x in the main thread and print it */</span><span class="w"></span>
<span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;x = {}&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="w"> </span><span class="cm">/* Join the thread and print x again */</span><span class="w"></span>
<span class="w"> </span><span class="n">child_thread</span><span class="p">.</span><span class="n">join</span><span class="p">();</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>
</td></tr></table></div>
<p>However, there is a subtle point in this code that is central to Rusts design.
Within the new thread (executing the code in the closure), the <code class="docutils literal notranslate"><span class="pre">x</span></code> variable is
distinct from the <code class="docutils literal notranslate"><span class="pre">x</span></code> in other parts of this code. Rust enforces a very strict
memory model (known as <em>ownership</em>) which prevents multiple threads from
accessing the same memory. In this example, the move keyword indicates that the
spawned thread will receive a separate copy of <code class="docutils literal notranslate"><span class="pre">x</span></code> for its own use. Regardless
of the scheduling of the two threads, the main and child threads cannot
interfere with each others modifications of <code class="docutils literal notranslate"><span class="pre">x</span></code>, because they are distinct
copies. It is impossible for the two threads to share access to the same memory.</p>
<p>In this small example, the issue of ownership may not seem to be a big deal.
However, if you learn more about Rust and concurrency, youll quickly realize
that it is. Ownership makes Rust very unique and makes it a very powerful
language for concurrent programming. The crux is that ownership completely
eliminates several types of race conditions, since it is impossible for multiple
threads to share the same memory location. Furthermore, it achieves this memory
safety <strong>without imposing any run-time performance penalty</strong>. Ownership
constraints are checked and enforced at compile-time. This combination of memory
safety and efficient performance gives Rust a significant advantage over other
languages in regard to multithreading.</p>
<div
id="ImplicitThreadSumm"
class="embedContainer"
data-exer-name="ImplicitThreadSumm"
data-long-name="Implicit threading questions"
data-short-name="ImplicitThreadSumm"
data-frame-src="../../../Exercises/Threads/ImplicitThreadSumm.html?selfLoggingEnabled=false&amp;localMode=true&amp;module=ImplicitThreads&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="ImplicitThreadSumm_iframe"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="mt-4 container center">
«&#160;&#160;<a id="prevmod1" href="ThreadArgs.html">6.5. Thread Arguments and Return Values</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod1" href="Extended6Input.html">6.7. Extended Example: Keyboard Input Listener</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>