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

479 lines
35 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.4. POSIX Thread Library &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="5. Thread Arguments and Return Values" href="ThreadArgs.html" />
<link rel="prev" title="3. Race Conditions and Critical Sections" href="RaceConditions.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="POSIXThreads.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="POSIXThreads.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/POSIXThreads.rst"
target="_blank" rel="nofollow">Show Source</a></li>
</ul>
</nav>
<div class="container center">
«&#160;&#160;<a id="prevmod" href="RaceConditions.html">6.3. Race Conditions and Critical Sections</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod" href="ThreadArgs.html">6.5. Thread Arguments and Return Values</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 = "POSIXThreads";ODSA.SETTINGS.MODULE_LONG_NAME = "POSIX Thread Library";ODSA.SETTINGS.MODULE_CHAPTER = "Concurrency with Multithreading"; ODSA.SETTINGS.BUILD_DATE = "2021-06-11 17:38:24"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="posix-thread-library">
<h1>6.4. POSIX Thread Library<a class="headerlink" href="POSIXThreads.html#posix-thread-library" title="Permalink to this headline"></a></h1>
<p>In this section, well return to the code from <a class="reference external" href="ProcVThreads.html#cl6-1">Code Listing 6.1</a> and replace the comments with functions from the
<a class="reference internal" href="Glossary.html#term-posix-thread-library"><span class="xref std std-term">POSIX thread library (pthreads)</span></a>. Pthread implementations
are available for a wide variety of platforms, including Linux, macOS, and
Windows. After considering the basic techniques to get threads started, well
look at how to pass arguments to and return data from the thread.</p>
<div class="section" id="creating-and-joining-threads">
<h2>6.4.1. Creating and Joining Threads<a class="headerlink" href="POSIXThreads.html#creating-and-joining-threads" title="Permalink to this headline"></a></h2>
<p>Three functions define the core functionality for creating and managing threads.
The <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> function will create and start a new thread inside a
process. The <code class="docutils literal notranslate"><span class="pre">start_routine</span></code> parameter specifies the name of the function to
use as the threads entry point, just as <code class="docutils literal notranslate"><span class="pre">main()</span></code> serves as the main threads
entry point. The pthread_exit() is used to exit the current thread and
optionally return a value. Finally, the <code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code> function is the
thread equivalent of the <code class="docutils literal notranslate"><span class="pre">wait()</span></code> function for processes. That is, calling
<code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code> on a child thread will cause the current (parent) thread to
wait until the child finishes and calls <code class="docutils literal notranslate"><span class="pre">pthread_exit()</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 &lt;pthread.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">pthread_create</span> <span class="pre">(pthread_t</span> <span class="pre">*thread,</span> <span class="pre">const</span> <span class="pre">pthread_attr_t</span> <span class="pre">*attr,</span> <span class="pre">void</span> <span class="pre">*(*start_routine)(void*),</span> <span class="pre">void</span> <span class="pre">*arg);</span></code></dt>
<dd>Create a new thread starting with at the <code class="docutils literal notranslate"><span class="pre">start_routine</span></code> function.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">pthread_exit</span> <span class="pre">(void</span> <span class="pre">*value_ptr);</span></code></dt>
<dd>Exit from the current thread.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">pthread_join</span> <span class="pre">(pthread_t</span> <span class="pre">thread,</span> <span class="pre">void</span> <span class="pre">**value_ptr);</span></code></dt>
<dd>Join a specified thread.</dd>
</dl>
</div>
<p>The arg argument to the <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> function gets passed verbatim as
the argument to the <code class="docutils literal notranslate"><span class="pre">start_routine()</span></code> function. That is, when the thread is
created, it begins executing as if the programmer had called <code class="docutils literal notranslate"><span class="pre">start_routine</span>
<span class="pre">(arg);</span></code> in their code. The only thing that is different is that the function
will begin executing in a different thread.</p>
<p>The prototype for the <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> function can be rather difficult to
read if you are not completely comfortable with <a class="reference internal" href="Glossary.html#term-function-pointer"><span class="xref std std-term">function pointers</span></a>. Specifically, this prototype declares that the third
parameter must be a pointer to a function that adheres to the following type
declaration:</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="kt">void</span> <span class="o">*</span><span class="nf">start_routine</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">args</span><span class="p">);</span>
</pre></div>
</div>
<p>This prototype requirement simplifies the interface specification for thread
creation. The trade-off is that passing parameters becomes more complicated. The
following program illustrates how to create a child thread and wait for it to finish.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-2"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.2:</span>
<span class="cm"> A POSIX thread version of &quot;Hello world&quot;</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;pthread.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;assert.h&gt;</span><span class="cp"></span>
<span class="cm">/* Function that will run in the child thread */</span>
<span class="kt">void</span> <span class="o">*</span>
<span class="nf">start_thread</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="n">printf</span> <span class="p">(</span><span class="s">&quot;Hello from child</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">pthread_exit</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</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="n">pthread_t</span> <span class="n">child_thread</span><span class="p">;</span>
<span class="cm">/* Create a child thread running start_thread() */</span>
<span class="n">assert</span> <span class="p">(</span><span class="n">pthread_create</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">child_thread</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">start_thread</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
<span class="cm">/* Wait for the child to finish, then exit */</span>
<span class="n">pthread_join</span> <span class="p">(</span><span class="n">child_thread</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="n">pthread_exit</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p><a class="reference external" href="POSIXThreads.html#cl6-2">Code Listing 6.2</a> illustrates a subtle point that is not immediately
obvious to novices: <strong>The ``main()`` function defines a thread.</strong> Specifically,
every program begins with a single thread of execution with <code class="docutils literal notranslate"><span class="pre">main()</span></code> as its
entry point. Once the pthread library creates an additional thread, it is
important that <code class="docutils literal notranslate"><span class="pre">main()</span></code> should be treated as a thread. In the simplest terms,
this perspective implies that <code class="docutils literal notranslate"><span class="pre">main()</span></code> needs to end with <code class="docutils literal notranslate"><span class="pre">pthread_exit()</span></code>
instead of the standard return statement. Using <code class="docutils literal notranslate"><span class="pre">pthread_exit()</span></code> ensures that
all threads are managed and run correctly.</p>
<p>The main thread uses <code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code> function to wait for the thread running
<code class="docutils literal notranslate"><span class="pre">start_thread()</span></code> to call <code class="docutils literal notranslate"><span class="pre">pthread_exit()</span></code>. The standard thread terminology
uses the term <a class="reference internal" href="Glossary.html#term-fork-join-pattern"><span class="xref std std-term">joining</span></a> to mean waiting on a thread to complete. When a
thread exits, any resources associated with it (such as its run-time stack)
remain allocated until the thread is joined. As such, the <code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code> and
<code class="docutils literal notranslate"><span class="pre">pthread_exit()</span></code> combination can be used to return a value from the exiting
thread to its parent. In this example, nothing is returned, so both of these
functions take NULL as an argument.</p>
<p>Creating threads with <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> happens <a class="reference internal" href="Glossary.html#term-asynchronous"><span class="xref std std-term">asynchronously</span></a>. That
is, <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> requests the allocation of resources for a new thread
and returns 0 if the request is successful. <strong>The new thread may or may not
begin running by the time ``pthread_create()`` returns.</strong> In fact, the new
thread may have already run to completion by the time <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code>
returns! The timing for running both the new and existing threads are determined
by the system (the pthread library and the kernel). From the programmers
perspective, this choice is nondeterministic.</p>
<div class="topic border border-dark rounded-lg alert-danger px-2 mb-3">
<div class="figure align-left">
<a class="reference internal image-reference" href="_images/CSF-Images-BugWarning.png"><img alt="Decorative bug warning" src="_images/CSF-Images-BugWarning.png" style="width: 90%;" /></a>
</div>
<p class="topic-title first pt-2 mb-1">Bug Warning</p><hr class="mt-1" />
<p>There are a couple of common mistakes with pthread function parameters. With
<code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code>, the first parameter must point to a <code class="docutils literal notranslate"><span class="pre">pthread_t</span></code>
instance. It is common to (incorrectly) declare the variable as a
<code class="docutils literal notranslate"><span class="pre">pthread_t*</span></code>. Instead, the variable should be a <code class="docutils literal notranslate"><span class="pre">pthread_t</span></code> and the address
of it should be passed as shown above. Similarly, the first parameter for
<code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code> must be a <code class="docutils literal notranslate"><span class="pre">pthread_t</span></code> instance, not a pointer. Next, the
third parameter to <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> must be the name of the function and
must not include (). The parentheses would indicate that the function should be
called (before creating the thread) and the functions return value specifies
the address to start at in the new thread. The following code sample
illustrates these bugs.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
2
3
4
5
6</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* WRONG! thread should not be a pointer in this example */</span>
<span class="n">pthread_t</span> <span class="o">*</span><span class="kr">thread</span><span class="p">;</span>
<span class="cm">/* WRONG! thread is invalid pointer and start should not have () */</span>
<span class="n">pthread_create</span> <span class="p">(</span><span class="kr">thread</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">start</span> <span class="p">(),</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="cm">/* WRONG! pthread_join() doesn&#39;t take pointer as first parameter */</span>
<span class="n">pthread_join</span> <span class="p">(</span><span class="kr">thread</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="attached-and-detached-threads">
<h2>6.4.2. Attached and Detached Threads<a class="headerlink" href="POSIXThreads.html#attached-and-detached-threads" title="Permalink to this headline"></a></h2>
<p>In some scenarios, a thread will be created as <a class="reference internal" href="Glossary.html#term-detached-thread"><span class="xref std std-term">detached</span></a> instead of
joinable. When a detached thread exits, its resources are immediately reclaimed
for more efficient reuse. However, once a thread is detached, it can never be
joined. This means that no other thread can wait on it to finish. According to
the pthread specification, all threads are supposed to be created as joinable by
default. The <code class="docutils literal notranslate"><span class="pre">pthread_attr_setdetachstate()</span></code> function can be used to change
the <code class="docutils literal notranslate"><span class="pre">attr</span></code> argument to <code class="docutils literal notranslate"><span class="pre">PTHREAD_CREATE_DETACHED</span></code> to override the default.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-3"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="n">pthread_attr_t</span> <span class="n">attr</span><span class="p">;</span>
<span class="cm">/* Get the default set of attributes */</span>
<span class="n">pthread_attr_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">attr</span><span class="p">);</span>
<span class="cm">/* Mark the thread as detached */</span>
<span class="n">pthread_attr_setdetachstate</span><span class="p">(</span><span class="o">&amp;</span><span class="n">attr</span><span class="p">,</span> <span class="n">PTHREAD_CREATE_DETACHED</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>Alternatively, the <code class="docutils literal notranslate"><span class="pre">pthread_detach()</span></code> function can be used to detach a running thread instance. A thread can detach itself by using its own <code class="docutils literal notranslate"><span class="pre">pthread_t</span></code> identifier as an argument to <code class="docutils literal notranslate"><span class="pre">pthread_detach()</span></code>.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-2 mb-3 notranslate" id="cl6-4"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="n">pthread_detach</span> <span class="p">(</span><span class="n">pthread_self</span> <span class="p">());</span>
</pre></div>
</div>
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
<div class="figure align-left">
<a class="reference internal image-reference" href="_images/CSF-Images-Library.png"><img alt="Decorative C library image" src="_images/CSF-Images-Library.png" style="width: 100%;" /></a>
</div>
<p class="topic-title first pt-2 mb-1">C library functions &lt;pthread.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">pthread_detach</span> <span class="pre">(pthread_t</span> <span class="pre">thread);</span></code></dt>
<dd>Detaches the specified thread.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">pthread_t</span> <span class="pre">pthread_self</span> <span class="pre">(void);</span></code></dt>
<dd>Returns the current threads pthread_t identifier.</dd>
</dl>
</div>
<div
id="POSIXThreadSumm"
class="embedContainer"
data-exer-name="POSIXThreadSumm"
data-long-name="POSIX thread questions"
data-short-name="POSIXThreadSumm"
data-frame-src="../../../Exercises/Threads/POSIXThreadSumm.html?selfLoggingEnabled=false&amp;localMode=true&amp;module=POSIXThreads&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="3"
data-type="ka"
data-exer-id="">
<div class="center">
<div id="POSIXThreadSumm_iframe"></div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="mt-4 container center">
«&#160;&#160;<a id="prevmod1" href="RaceConditions.html">6.3. Race Conditions and Critical Sections</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod1" href="ThreadArgs.html">6.5. Thread Arguments and Return Values</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>