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

970 lines
No EOL
69 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.5. Thread Arguments and Return Values &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="6. Implicit Threading and Language-based Threads" href="ImplicitThreads.html" />
<link rel="prev" title="4. POSIX Thread Library" href="POSIXThreads.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="ThreadArgs.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="ThreadArgs.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/ThreadArgs.rst"
target="_blank" rel="nofollow">Show Source</a></li>
</ul>
</nav>
<div class="container center">
«&#160;&#160;<a id="prevmod" href="POSIXThreads.html">6.4. POSIX Thread Library</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod" href="ImplicitThreads.html">6.6. Implicit Threading and Language-based Threads</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 = "ThreadArgs";ODSA.SETTINGS.MODULE_LONG_NAME = "Thread Arguments and Return Values";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="thread-arguments-and-return-values">
<h1>6.5. Thread Arguments and Return Values<a class="headerlink" href="ThreadArgs.html#thread-arguments-and-return-values" title="Permalink to this headline"></a></h1>
<p>The <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> imposes a strict format on the prototype of the
function that will run in the new thread. It must take a single <code class="docutils literal notranslate"><span class="pre">void*</span></code>
parameter and return a single <code class="docutils literal notranslate"><span class="pre">void*</span></code> value. The last parameter of
<code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> is passed as the argument to the function, whereas the
return value is passed using <code class="docutils literal notranslate"><span class="pre">pthread_exit()</span></code> and <code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code>. This
section looks at the details of these mechanisms and their implications.</p>
<div class="section" id="passing-a-single-argument-to-threads">
<h2>6.5.1. Passing a Single Argument to Threads<a class="headerlink" href="ThreadArgs.html#passing-a-single-argument-to-threads" title="Permalink to this headline"></a></h2>
<p>Passing a single argument to a thread seems straightforward, but is easy to do
incorrectly. As a simple example to illustrate the danger, <a class="reference external" href="ThreadArgs.html#cl6-5">Code Listing 6.5</a>
is designed to run in a separate thread:</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-5"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.5:</span>
<span class="cm"> A thread that will print a single integer value</span>
<span class="cm"> */</span>
<span class="kt">void</span> <span class="o">*</span>
<span class="nf">child_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="cm">/* POTENTIALLY DANGEROUS TIMING */</span>
<span class="kt">int</span> <span class="o">*</span><span class="n">argptr</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span> <span class="o">*</span><span class="p">)</span> <span class="n">args</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">arg</span> <span class="o">=</span> <span class="o">*</span><span class="n">argptr</span><span class="p">;</span>
<span class="cm">/* Print the local copy of the argument */</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Argument is %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">arg</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>The danger of this code can be illustrated with the loop in <a class="reference external" href="ThreadArgs.html#cl6-6">Code Listing 6.6</a>.
The intent is to pass the value 1 to the first thread, 2 to the
second, and so on. However, it is critical to note that <strong>there is only a single
copy of the</strong> <code class="docutils literal notranslate"><span class="pre">i</span></code> <strong>variable</strong>. That is, this code passes the address of the
single variable to all 10 threads; the code almost certainly does not pass the
intended values.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-6"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.6:</span>
<span class="cm"> Passing a pointer to a variable that repeatedly changes is a common error with threads</span>
<span class="cm"> */</span>
<span class="cm">/* BAD CODE - DON&#39;T DO THIS */</span>
<span class="cm">/* What value is actually passed to the thread? */</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</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</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">child_thread</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">i</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>The key problem is that thread creation and execution is <a class="reference internal" href="Glossary.html#term-asynchronous"><span class="xref std std-term">asynchronous</span></a>.
That means that it is impossible to predict when each of the new threads start
running. One possible timing is that all 10 threads are created first, leading
to <code class="docutils literal notranslate"><span class="pre">i</span></code> storing the value 11. At that point, each of the threads dereference
their respective <code class="docutils literal notranslate"><span class="pre">argptr</span></code> variable and all get the same value of 11.</p>
<p>One common solution to this problem is to cast numeric values as pointers, as
shown in <a class="reference external" href="ThreadArgs.html#cl6-7">Code Listing 6.7</a>. That is, the int <code class="docutils literal notranslate"><span class="pre">i</span></code> variable gets cast
as a <code class="docutils literal notranslate"><span class="pre">(void*)</span></code> argument in the call to <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code>. Then, the
<code class="docutils literal notranslate"><span class="pre">void*</span></code> argument to <code class="docutils literal notranslate"><span class="pre">child_thread()</span></code> casts the argument back to a <code class="docutils literal notranslate"><span class="pre">int</span></code> instance.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-7"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.7:</span>
<span class="cm"> Each thread should be given a separate value, rather than a shared address</span>
<span class="cm"> */</span>
<span class="cm">/* FIXED VERSION */</span>
<span class="cm">/* ints are passed by value, so a COPY gets passed to each call */</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</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</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">child_thread</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="n">i</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>What makes this code work is the fact that scalar variables (e.g., <code class="docutils literal notranslate"><span class="pre">int</span></code>
variables) are passed using call-by-value semantics. When this code prepares for
the <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> call, a separate copy of the current value of the <code class="docutils literal notranslate"><span class="pre">i</span></code>
variable is placed into a register or onto the stack. <a class="reference external" href="ThreadArgs.html#cl6-8">Code Listing 6.8</a> shows the corrected version of <a class="reference external" href="ThreadArgs.html#cl6-5">Code Listing 6.5</a>. The
<code class="docutils literal notranslate"><span class="pre">child_thread()</span></code> function then gets this copy, regardless of any changes to
the original <code class="docutils literal notranslate"><span class="pre">i</span></code> variable. When the child thread then casts its <code class="docutils literal notranslate"><span class="pre">args</span></code>
parameter to a local <code class="docutils literal notranslate"><span class="pre">arg_value</span></code>, it is working with the correct value that was passed.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-8"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.8:</span>
<span class="cm"> A safer version of Code Listing 6.5</span>
<span class="cm"> */</span>
<span class="cm">/* Convention: It is common to name a void* parameter with a name</span>
<span class="cm"> that begins with _, then cast it to a local variable that has</span>
<span class="cm"> the same (or nearly the same) name without the _. So _args will</span>
<span class="cm"> become args. Recall that _ has no special meaning and is treated</span>
<span class="cm"> like a normal alphabetical character. */</span>
<span class="kt">void</span> <span class="o">*</span>
<span class="nf">child_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="cm">/* Safe whenever size of int &lt;= size of pointer (which is</span>
<span class="cm"> usually true) */</span>
<span class="kt">int</span> <span class="n">arg</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="n">_args</span><span class="p">;</span>
<span class="cm">/* Print the local copy of the argument */</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Argument is %ld</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">arg</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>
<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>Casting integral values to pointers and back again is a common practice for
passing parameters to pthreads. However, while it is generally safe in
practice, it is potentially a bug on some platforms. Specifically, this
technique relies on the fact that pointers are at least as large as standard
integer types. That is, <code class="docutils literal notranslate"><span class="pre">int</span></code> variables are typically (but not required to
be) 32 bits in size. Modern CPU architectures tend to use 32- or 64-bit
addresses. As such, casting a 32-bit <code class="docutils literal notranslate"><span class="pre">int</span></code> up to a <code class="docutils literal notranslate"><span class="pre">void*</span></code> then back to a
32-bit <code class="docutils literal notranslate"><span class="pre">int</span></code> is safe.</p>
<p>On the other hand, assume the argument was declared as a <code class="docutils literal notranslate"><span class="pre">long</span></code> variable
instance. If the code is running on a 32-bit architecture (which is not
uncommon for virtualized systems) but the <code class="docutils literal notranslate"><span class="pre">long</span></code> type is 64 bits in size,
then half of the argument is lost by down-casting to the pointer for the call
to <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code>!</p>
</div>
</div>
<div class="section" id="passing-multiple-arguments-to-threads">
<h2>6.5.2. Passing Multiple Arguments to Threads<a class="headerlink" href="ThreadArgs.html#passing-multiple-arguments-to-threads" title="Permalink to this headline"></a></h2>
<p>When passing multiple arguments to a child thread, the standard approach is to
group the arguments within a <code class="docutils literal notranslate"><span class="pre">struct</span></code> declaration, as shown in <a class="reference external" href="ThreadArgs.html#cl6-9">Code Listing
6.9</a>. The address of the <code class="docutils literal notranslate"><span class="pre">struct</span></code> instance gets passed as the
<code class="docutils literal notranslate"><span class="pre">arg</span></code> to <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code>. The new threads entry point receives a
<code class="docutils literal notranslate"><span class="pre">void*</span></code> parameter that can then be cast into the <code class="docutils literal notranslate"><span class="pre">struct</span></code> type.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-9"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.9:</span>
<span class="cm"> Passing multiple arguments to a thread requires grouping them into a struct</span>
<span class="cm"> */</span>
<span class="cm">/* Assume we have:</span>
<span class="cm"> struct thread_args {</span>
<span class="cm"> int first;</span>
<span class="cm"> const char *second;</span>
<span class="cm"> };</span>
<span class="cm"> */</span>
<span class="k">struct</span> <span class="n">thread_args</span> <span class="o">*</span><span class="n">args</span> <span class="o">=</span> <span class="n">malloc</span> <span class="p">(</span><span class="k">sizeof</span> <span class="p">(</span><span class="k">struct</span> <span class="n">thread_args</span><span class="p">));</span>
<span class="n">args</span><span class="o">-&gt;</span><span class="n">first</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">args</span><span class="o">-&gt;</span><span class="n">second</span> <span class="o">=</span> <span class="s">&quot;Hello&quot;</span><span class="p">;</span>
<span class="cm">/* Note that the data structure resides on the heap */</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</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">hello_thread</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p><a class="reference external" href="ThreadArgs.html#cl6-10">Code Listing 6.10</a> shows the new thread receiving the pointer to the
<code class="docutils literal notranslate"><span class="pre">struct</span></code> and freeing the allocated memory when it is finished with the data.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-10"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.10:</span>
<span class="cm"> The child thread receives multiple values through the passed struct</span>
<span class="cm"> */</span>
<span class="cm">/* Using the convention of casting _args to args */</span>
<span class="kt">void</span> <span class="o">*</span>
<span class="nf">hello_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="cm">/* Cast args into a meaningful pointer type that we can use */</span>
<span class="k">struct</span> <span class="n">thread_args</span> <span class="o">*</span><span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="k">struct</span> <span class="n">thread_args</span> <span class="o">*</span><span class="p">)</span> <span class="n">_args</span><span class="p">;</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;First: %d; Second: &#39;%s&#39;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">first</span><span class="p">,</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">second</span><span class="p">);</span>
<span class="cm">/* Do not forget to free the struct used for arguments */</span>
<span class="n">free</span> <span class="p">(</span><span class="n">args</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>
<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>A common mistake with passing arguments in this manner is to declare the
<code class="docutils literal notranslate"><span class="pre">struct</span></code> instance as a local variable instead of using dynamic allocation.
The problem, again, is the asynchronous nature of <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code>.
Consider this sample code:</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
7
8
9
10
11
12</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Create a local instance on the current thread&#39;s stack */</span>
<span class="k">struct</span> <span class="n">thread_args</span> <span class="n">args</span><span class="p">;</span>
<span class="n">args</span><span class="p">.</span><span class="n">first</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">args</span><span class="p">.</span><span class="n">second</span> <span class="o">=</span> <span class="s">&quot;Hello&quot;</span><span class="p">;</span>
<span class="cm">/* Pass a reference to the local instance */</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</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">hello_thread</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">args</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
<span class="cm">/* Parent thread exits, but the child may not have run yet */</span>
<span class="n">pthread_exit</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
<span class="cm">/* Future references to args are invalid! */</span>
</pre></div>
</td></tr></table></div>
</div>
<p>If the child thread runs immediately before <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> returns, then
everything would be fine. However, there is no guarantee that this happens.
Instead, it is just as likely that <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> returns and the parent
thread exits. Once that happens, all data on the parent threads stack
(including the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">thread_args</span></code> instance) become invalid. The child thread
now has a dangling pointer to potentially corrupted data. This is another
example of a race condition that can happen with threads.</p>
</div>
<div class="section" id="returning-values-from-threads">
<h2>6.5.3. Returning Values from Threads<a class="headerlink" href="ThreadArgs.html#returning-values-from-threads" title="Permalink to this headline"></a></h2>
<p>There are three common ways to get return values back from a thread. All three
use techniques that are similar to those used for passing arguments.
<a class="reference external" href="ThreadArgs.html#cl6-11">Code Listing 6.11</a> shows one simple technique, which is to augment
the <code class="docutils literal notranslate"><span class="pre">struct</span></code> declaration to include space for any return values.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-11"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.11:</span>
<span class="cm"> Allocating space for a return value as part of the struct passed</span>
<span class="cm"> */</span>
<span class="cm">/* Approach 1: Include space for return values in the struct */</span>
<span class="cm">/* Thread argument struct declaration */</span>
<span class="k">struct</span> <span class="n">numbers</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">a</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">b</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">sum</span><span class="p">;</span>
<span class="p">};</span>
<span class="kt">void</span> <span class="o">*</span>
<span class="nf">sum_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="cm">/* Cast the arguments to the usable struct type */</span>
<span class="k">struct</span> <span class="n">numbers</span> <span class="o">*</span><span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="k">struct</span> <span class="n">numbers</span> <span class="o">*</span><span class="p">)</span> <span class="n">_args</span><span class="p">;</span>
<span class="cm">/* Place the result into the struct itself (on the heap) */</span>
<span class="n">args</span><span class="o">-&gt;</span><span class="n">sum</span> <span class="o">=</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">a</span> <span class="o">+</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">b</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>The child thread receives a pointer to the <code class="docutils literal notranslate"><span class="pre">struct</span></code> instance, using the input
parameters as needed. In this case, the values of <code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">b</span></code> are added, and
the resulting sum is copied back into the <code class="docutils literal notranslate"><span class="pre">struct</span></code>. As shown in <a class="reference external" href="ThreadArgs.html#cl6-12">Code Listing
6.12</a>, the main thread uses <code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code> to wait until the
child thread exits. Once the child finishes, the main thread can retrieve all
three values (<code class="docutils literal notranslate"><span class="pre">a</span></code>, <code class="docutils literal notranslate"><span class="pre">b</span></code>, and <code class="docutils literal notranslate"><span class="pre">sum</span></code>) from the <code class="docutils literal notranslate"><span class="pre">struct</span></code> itself.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-12"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.12:</span>
<span class="cm"> The main thread can retrieve the return value from the struct after joining the child thread</span>
<span class="cm"> */</span>
<span class="cm">/* Allocate and pass a heap instance of the struct type */</span>
<span class="k">struct</span> <span class="n">numbers</span> <span class="o">*</span><span class="n">args</span> <span class="o">=</span> <span class="n">calloc</span> <span class="p">(</span><span class="k">sizeof</span> <span class="p">(</span><span class="k">struct</span> <span class="n">numbers</span><span class="p">),</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">args</span><span class="o">-&gt;</span><span class="n">a</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">args</span><span class="o">-&gt;</span><span class="n">b</span> <span class="o">=</span> <span class="mi">8</span><span class="p">;</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</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">sum_thread</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
<span class="cm">/* Wait for the thread to finish */</span>
<span class="n">pthread_join</span> <span class="p">(</span><span class="n">child</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="cm">/* The struct is still on the heap, so the result is accessible */</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;%d + %d = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">a</span><span class="p">,</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">b</span><span class="p">,</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">sum</span><span class="p">);</span>
<span class="cm">/* Clean up the struct instance */</span>
<span class="n">free</span> <span class="p">(</span><span class="n">args</span><span class="p">);</span>
<span class="n">args</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</pre></div>
</td></tr></table></div>
<p>There are three key observations about this approach:</p>
<blockquote>
<div><ul class="simple">
<li>The main and the child threads have access to both the input and the output.
This fact means that the main thread has information about how this particular
child thread was invoked. If the main thread is keeping track of many threads,
this additional information may be helpful.</li>
<li>Responsibility for memory management resides in one location: the main thread.
If responsibility is split between the programmer maintaining the main thread
and the programmer maintaining the child thread, there is the possibility for
miscommunication leading to memory leaks (or worse, premature de-allocation).</li>
<li>The major disadvantage of this approach is that the input parameters may be
kept on the heap for much longer than needed, particularly if the child thread
runs for a significant amount of time.</li>
</ul>
</div></blockquote>
<p><a class="reference external" href="ThreadArgs.html#cl6-13">Code Listing 6.13</a> shows an alternative approach for simple scalar
return types, which is to reuse the trick of casting to and from the <code class="docutils literal notranslate"><span class="pre">void*</span></code>
type. When a thread calls <code class="docutils literal notranslate"><span class="pre">pthread_exit()</span></code>, it can specify a pointer to return
as an argument.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-13"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.13:</span>
<span class="cm"> A second technique to return a value is to pass it as the threads exit code</span>
<span class="cm"> */</span>
<span class="cm">/* Approach 2: Scalar return types as void* with pthread_exit() */</span>
<span class="cm">/* Thread argument struct contains only input parameters */</span>
<span class="k">struct</span> <span class="n">numbers</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">a</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">b</span><span class="p">;</span>
<span class="p">};</span>
<span class="kt">void</span> <span class="o">*</span>
<span class="nf">sum_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="cm">/* Cast the argument to the usable struct */</span>
<span class="k">struct</span> <span class="n">numbers</span> <span class="o">*</span><span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="k">struct</span> <span class="n">numbers</span> <span class="o">*</span><span class="p">)</span> <span class="n">_args</span><span class="p">;</span>
<span class="cm">/* Pass the result back by casting it to the void* */</span>
<span class="n">pthread_exit</span> <span class="p">((</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span> <span class="p">(</span><span class="n">args</span><span class="o">-&gt;</span><span class="n">a</span> <span class="o">+</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">b</span><span class="p">));</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p><a class="reference external" href="ThreadArgs.html#cl6-14">Code Listing 6.14</a> shows how the main thread calls
<code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code> to retrieve the pointer. Unless the thread has been detached
(or it was created with the <code class="docutils literal notranslate"><span class="pre">PTHREAD_CREATE_DETACHED</span></code> attribute), the pointer
returned with <code class="docutils literal notranslate"><span class="pre">pthread_exit()</span></code> will remain associated with the thread until it
is joined.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-14"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.14:</span>
<span class="cm"> Retrieving a threads exit code when it is joined</span>
<span class="cm"> */</span>
<span class="cm">/* Allocate the struct like before and pass it to the thread */</span>
<span class="k">struct</span> <span class="n">numbers</span> <span class="o">*</span><span class="n">args</span> <span class="o">=</span> <span class="n">calloc</span> <span class="p">(</span><span class="k">sizeof</span> <span class="p">(</span><span class="k">struct</span> <span class="n">numbers</span><span class="p">),</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">args</span><span class="o">-&gt;</span><span class="n">a</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">args</span><span class="o">-&gt;</span><span class="n">b</span> <span class="o">=</span> <span class="mi">8</span><span class="p">;</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</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">sum_thread</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
<span class="cm">/* Wait for thread to finish and retrieve the void* into sum */</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">sum</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">pthread_join</span> <span class="p">(</span><span class="n">child</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">sum</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Sum: %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="n">sum</span><span class="p">);</span>
<span class="n">free</span> <span class="p">(</span><span class="n">args</span><span class="p">);</span>
<span class="n">args</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">;</span>
</pre></div>
</td></tr></table></div>
<p><a class="reference external" href="ThreadArgs.html#cl6-15">Code Listing 6.15</a> shows a third approach to returning values from
the thread. In this style, the child thread allocates a separate <code class="docutils literal notranslate"><span class="pre">struct</span></code>
dynamically to hold the return values. This technique allows a thread to return
multiple values rather than a single scalar. For instance, consider the
following <code class="docutils literal notranslate"><span class="pre">calculator</span></code> thread. It receives two <code class="docutils literal notranslate"><span class="pre">int</span></code> values as input and
returns the results of five simple arithmetic operations.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-15"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.15:</span>
<span class="cm"> The child can dynamically allocate space for the return values</span>
<span class="cm"> */</span>
<span class="cm">/* Approach 3: Allocate separate struct for return values */</span>
<span class="cm">/* struct for passing arguments to the child thread */</span>
<span class="k">struct</span> <span class="n">args</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">a</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">b</span><span class="p">;</span>
<span class="p">};</span>
<span class="cm">/* struct for returning results from the child thread */</span>
<span class="k">struct</span> <span class="n">results</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">sum</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">difference</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">product</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">quotient</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">modulus</span><span class="p">;</span>
<span class="p">};</span>
<span class="kt">void</span> <span class="o">*</span>
<span class="nf">calculator</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="cm">/* Cast the args to the usable struct type */</span>
<span class="k">struct</span> <span class="n">args</span> <span class="o">*</span><span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="k">struct</span> <span class="n">args</span> <span class="o">*</span><span class="p">)</span> <span class="n">_args</span><span class="p">;</span>
<span class="cm">/* Allocate heap space for this thread&#39;s results */</span>
<span class="k">struct</span> <span class="n">results</span> <span class="o">*</span><span class="n">results</span> <span class="o">=</span> <span class="n">calloc</span> <span class="p">(</span><span class="k">sizeof</span> <span class="p">(</span><span class="k">struct</span> <span class="n">results</span><span class="p">),</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">results</span><span class="o">-&gt;</span><span class="n">sum</span> <span class="o">=</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">a</span> <span class="o">+</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">b</span><span class="p">;</span>
<span class="n">results</span><span class="o">-&gt;</span><span class="n">difference</span> <span class="o">=</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">a</span> <span class="o">-</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">b</span><span class="p">;</span>
<span class="n">results</span><span class="o">-&gt;</span><span class="n">product</span> <span class="o">=</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">a</span> <span class="o">*</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">b</span><span class="p">;</span>
<span class="n">results</span><span class="o">-&gt;</span><span class="n">quotient</span> <span class="o">=</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">a</span> <span class="o">/</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">b</span><span class="p">;</span>
<span class="n">results</span><span class="o">-&gt;</span><span class="n">modulus</span> <span class="o">=</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">a</span> <span class="o">%</span> <span class="n">args</span><span class="o">-&gt;</span><span class="n">b</span><span class="p">;</span>
<span class="cm">/* De-allocate the input instance and return the pointer to</span>
<span class="cm"> results on heap */</span>
<span class="n">free</span> <span class="p">(</span><span class="n">args</span><span class="p">);</span>
<span class="n">pthread_exit</span> <span class="p">(</span><span class="n">results</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p>It is critical to note that the struct instance here must be allocated
dynamically. Once the thread calls <code class="docutils literal notranslate"><span class="pre">pthread_exit()</span></code>, everything on its stack
becomes invalid. A thread should never pass a pointer to a local variable with
<code class="docutils literal notranslate"><span class="pre">pthread_exit()</span></code>.</p>
<p>Retrieving the returned data can be accomplished with <code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code>. In the
following example, the main thread creates five separate instances of the
<code class="docutils literal notranslate"><span class="pre">calculator</span></code> thread. Each of these child threads gets a pointer to a unique
<code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">args</span></code> instance with the corresponding parameters. Each child then
allocates its own <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">results</span></code> instance on the heap. This allows the data
to persist after the thread has finished. In <a class="reference external" href="ThreadArgs.html#cl6-14">Code Listing 6.14</a>, the
main thread gets each threads pointer one at a time, with a separate call to
<code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code>. Since the child thread has already finished at this point,
the main thread must bear the responsibility for calling <code class="docutils literal notranslate"><span class="pre">free()</span></code> to
de-allocate the <code class="docutils literal notranslate"><span class="pre">struct</span></code> results instance.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl6-16"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 6.16:</span>
<span class="cm"> The main thread passes arguments to the child threads and frees the results</span>
<span class="cm"> */</span>
<span class="cm">/* Create 5 threads, each calling calculator() */</span>
<span class="n">pthread_t</span> <span class="n">child</span><span class="p">[</span><span class="mi">5</span><span class="p">];</span>
<span class="cm">/* Allocate arguments and create the threads */</span>
<span class="k">struct</span> <span class="n">args</span> <span class="o">*</span><span class="n">args</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">};</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">5</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* args[i] is a pointer to the arguments for thread i */</span>
<span class="n">args</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">calloc</span> <span class="p">(</span><span class="k">sizeof</span> <span class="p">(</span><span class="k">struct</span> <span class="n">args</span><span class="p">),</span> <span class="mi">1</span><span class="p">);</span>
<span class="cm">/* thread 0 calls calculator(1,1)</span>
<span class="cm"> thread 1 calls calculator(2,4)</span>
<span class="cm"> thread 2 calls calculator(3,9)</span>
<span class="cm"> and so on... */</span>
<span class="n">args</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">a</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">args</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</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</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">calculator</span><span class="p">,</span> <span class="n">args</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
<span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Allocate an array of pointers to result structs */</span>
<span class="k">struct</span> <span class="n">results</span> <span class="o">*</span><span class="n">results</span><span class="p">[</span><span class="mi">5</span><span class="p">];</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">5</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* Passing results[i] by reference creates (void **) */</span>
<span class="n">pthread_join</span> <span class="p">(</span><span class="n">child</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="p">(</span><span class="kt">void</span> <span class="o">**</span><span class="p">)</span><span class="o">&amp;</span><span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="cm">/* Print each of the results and free the struct */</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Calculator (%d, %2d) ==&gt; &quot;</span><span class="p">,</span> <span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">));</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;+:%3d; &quot;</span><span class="p">,</span> <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">sum</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;-:%3d; &quot;</span><span class="p">,</span> <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">difference</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;*:%3d; &quot;</span><span class="p">,</span> <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">product</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;/:%3d; &quot;</span><span class="p">,</span> <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">quotient</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;%%:%3d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">modulus</span><span class="p">);</span>
<span class="n">free</span> <span class="p">(</span><span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<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>All of the functions for creating threads, passing arguments, and getting return
values involve a lot of pointers. Furthermore, the pointers are dereferenced
and manipulated asynchronously because of the nature of multithreading. It is
vital to remember the types and lifetimes of each pointer and the corresponding data structure.</p>
<blockquote>
<div><ul class="simple">
<li>The first parameter for <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> is a <code class="docutils literal notranslate"><span class="pre">pthread_t*</span></code>. The argument
should typically be an existing <code class="docutils literal notranslate"><span class="pre">pthread_t</span></code> passed by reference with the <code class="docutils literal notranslate"><span class="pre">&amp;</span></code> operator.</li>
<li>The final parameter to <code class="docutils literal notranslate"><span class="pre">pthread_create()</span></code> must either be a scalar (cast as a
pointer) or a pointer to data that persists until the child thread runs. That
is, the target of the pointer must not be modified by the main thread until the
child thread has been joined (to guarantee the child has run).</li>
<li>The parameter to <code class="docutils literal notranslate"><span class="pre">pthread_exit()</span></code> must be a scalar value (cast as a pointer)
or a pointer to non-stack data. The data must be guaranteed to be valid even
after the thread has been completely destroyed.</li>
<li>The final parameter to <code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code> must be a pointer that is passed by
reference. That is, <code class="docutils literal notranslate"><span class="pre">pthread_join()</span></code> will change this pointer to point to the
returned data structure.</li>
</ul>
</div></blockquote>
</div>
<div
id="ThreadArgsSumm"
class="embedContainer"
data-exer-name="ThreadArgsSumm"
data-long-name="Thread argument questions"
data-short-name="ThreadArgsSumm"
data-frame-src="../../../Exercises/Threads/ThreadArgsSumm.html?selfLoggingEnabled=false&amp;localMode=true&amp;module=ThreadArgs&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="ThreadArgsSumm_iframe"></div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="mt-4 container center">
«&#160;&#160;<a id="prevmod1" href="POSIXThreads.html">6.4. POSIX Thread Library</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod1" href="ImplicitThreads.html">6.6. Implicit Threading and Language-based Threads</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>