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

705 lines
59 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>2.5. Process Life Cycle &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. The UNIX File Abstraction" href="UnixFile.html" />
<link rel="prev" title="4. System Call Interface" href="Syscall.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="ProcessCycle.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="ProcessCycle.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/ProcessCycle.rst"
target="_blank" rel="nofollow">Show Source</a></li>
</ul>
</nav>
<div class="container center">
«&#160;&#160;<a id="prevmod" href="Syscall.html">2.4. System Call Interface</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod" href="UnixFile.html">2.6. The UNIX File Abstraction</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 = "ProcessCycle";ODSA.SETTINGS.MODULE_LONG_NAME = "Process Life Cycle";ODSA.SETTINGS.MODULE_CHAPTER = "Processes and OS Basics"; ODSA.SETTINGS.BUILD_DATE = "2021-10-29 11:55:12"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="process-life-cycle">
<h1>2.5. Process Life Cycle<a class="headerlink" href="ProcessCycle.html#process-life-cycle" title="Permalink to this headline"></a></h1>
<p>From a very high-level perspective, we can describe the life cycle of a process as a sequence of
<a class="reference internal" href="Glossary.html#term-event"><span class="xref std std-term">events</span></a>. The first event is the creation of the process as a new virtual memory
instance. The CPU will then begin executing the program code according to the
<em>von Neumann instruction cycle</em> until it reaches the <code class="docutils literal notranslate"><span class="pre">halt</span></code> instruction indicating the
program is complete. At that point, the process is destroyed and any resources (such as physical
memory) associated with it are reclaimed by the kernel.</p>
<div class="section" id="process-creation">
<h2>2.5.1. Process Creation<a class="headerlink" href="ProcessCycle.html#process-creation" title="Permalink to this headline"></a></h2>
<p>There are generally two system calls that are associated with creating a new process: <code class="docutils literal notranslate"><span class="pre">fork()</span></code> and
<code class="docutils literal notranslate"><span class="pre">exec()</span></code>. When a program calls <code class="docutils literal notranslate"><span class="pre">fork()</span></code>, a system call is triggered that asks the kernel to
create a new virtual memory instance. In the immediate moment when this occurs, the contents of the
new virtual memory instance is an exact duplicate of the process that was running. We refer to the
two processes as the <em>parent</em> and <em>child</em>. While
handling the <code class="docutils literal notranslate"><span class="pre">fork()</span></code>, the kernel will allocate new internal data structures for the child, assign
it a <a class="reference internal" href="Glossary.html#term-process-identifier"><span class="xref std std-term">process identifier</span></a> (PID), and assign a small set of initial resources to it. A PID is
an integer value that acts like a name that can be used to uniquely refer to a process.</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;unistd.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">pid_t&nbsp;fork(void);</span></code></dt>
<dd>Creates a new process. Returns the childs PID if successful.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">pid_t&nbsp;getpid(void);</span></code></dt>
<dd>Gets the current processs PID.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">pid_t&nbsp;getppid(void);</span></code></dt>
<dd>Gets the PID of the current processs parent.</dd>
</dl>
</div>
<p><a class="reference external" href="ProcessCycle.html#cl2-6">Code Listing 2.6</a> demonstrates how to use <code class="docutils literal notranslate"><span class="pre">fork()</span></code>. Once both processes are running, the code can
distinguish between the parent and child by looking at the value returned from <code class="docutils literal notranslate"><span class="pre">fork()</span></code>.The kernel
returns 0 to the child, and it returns the childs PID to the parent. If the kernel failed or
refused to create a new process for some reason, it would return a negative value to the parent; the
global variable <code class="docutils literal notranslate"><span class="pre">errno</span></code> (declared in the standard library file <code class="docutils literal notranslate"><span class="pre">errno.h</span></code>) would be set to an
integer value indicating the error that occurred.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-6"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 2.6:</span>
<span class="cm"> Using fork() to create a child process and access its PID</span>
<span class="cm"> */</span>
<span class="kt">pid_t</span> <span class="n">child_pid</span> <span class="o">=</span> <span class="n">fork</span> <span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;ERROR: No child process created</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="nf">if</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Hi, I am the child!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span>
<span class="nf">printf</span> <span class="p">(</span><span class="s">&quot;Parent just learned about child %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">child_pid</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>The return values from <code class="docutils literal notranslate"><span class="pre">fork()</span></code> make sense when you consider that the C library defines two
functions that allow the process to determine its own PID (<code class="docutils literal notranslate"><span class="pre">getpid()</span></code>) and to find out its
parents PID (<code class="docutils literal notranslate"><span class="pre">getppid()</span></code>). The child can use these two functions to identify itself and its
parent. However, the parent process may have already created dozens of child processes. The return
value from <code class="docutils literal notranslate"><span class="pre">fork()</span></code> informs the parent of the PID for this new child process that was just created.</p>
<p><a class="reference external" href="ProcessCycle.html#cl2-7">Code Listing 2.7</a> shows an example of what happens when the return code from <code class="docutils literal notranslate"><span class="pre">fork()</span></code> is not
checked. On line 6, the original process creates a child. For clarity, let the original process of
PID 1000 and this child has PID 1001. Since both processes continue to execute with the same code,
both reach line 9 and create two additional processes (PIDs 1002 and 1003). As a result, there would
be four processes that execute line 12, printing the message four times (with different PIDs each time).</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-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
9
10
11
12
13</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 2.7:</span>
<span class="cm"> Running the same code in multiple processes</span>
<span class="cm"> */</span>
<span class="cm">/* Start by creating a second process */</span>
<span class="kt">pid_t</span> <span class="n">first_fork</span> <span class="o">=</span> <span class="n">fork</span> <span class="p">();</span>
<span class="cm">/* BOTH the original parent and child create new processes */</span>
<span class="kt">pid_t</span> <span class="n">second_fork</span> <span class="o">=</span> <span class="n">fork</span> <span class="p">();</span>
<span class="cm">/* This line will print four times */</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Hello world from %d!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">getpid</span> <span class="p">());</span>
</pre></div>
</td></tr></table></div>
<p>It may seem odd that <code class="docutils literal notranslate"><span class="pre">fork()</span></code> would create a new process running the exact same code as the
parent. However, there are several times where this makes sense. Consider a web browser, such as
Google Chrome. Whenever you open a new tab, Chrome will make a call to <code class="docutils literal notranslate"><span class="pre">fork()</span></code> to create a new
process for that tab. Intuitively, all tabs in a web browser work the same way: they get a URL
request from the user and retrieve the corresponding web page or file from a server somewhere.
Consequently, it makes sense that all of the processes for Chrome would start with the same code
segment. Making the tabs run in separate processes provides some security and reliability: If a
plug-in crashes in one tab, only that tab is affected; the other tabs exist in other processes, so
they are isolated from the crash.</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>Once a process uses <code class="docutils literal notranslate"><span class="pre">fork()</span></code> to create a child process, the timing of the execution becomes
nondeterministic from the programmers point of view. The programmer cannot predict or control when
the child begins executing relative to the parent. In some systems, the child process may begin
executing immediately before the parent process returns from the call to <code class="docutils literal notranslate"><span class="pre">fork()</span></code>. In others, the
child may simply be created and start running at some later time. Consequently, if the order of the
execution matters, the programmer must take extra steps to ensure correct behavior; one example of
this is to use <code class="docutils literal notranslate"><span class="pre">wait()</span></code> as described below. We will examine more advanced techniques in later chapters.</p>
</div>
</div>
<div class="section" id="switching-program-code">
<h2>2.5.2. Switching Program Code<a class="headerlink" href="ProcessCycle.html#switching-program-code" title="Permalink to this headline"></a></h2>
<p>In many cases, after making a call to <code class="docutils literal notranslate"><span class="pre">fork()</span></code>, you want to switch to a different program. For
instance, consider the <code class="docutils literal notranslate"><span class="pre">bash</span></code> terminal program. Within <code class="docutils literal notranslate"><span class="pre">bash</span></code>, some commands are considered
<em>built-in</em> and are executed by <code class="docutils literal notranslate"><span class="pre">bash</span></code> itself. One example of a built-in is the export command,
which can be used to define or change an <a class="reference internal" href="Glossary.html#term-environment-variable"><span class="xref std std-term">environment variable</span></a>, such as <code class="docutils literal notranslate"><span class="pre">PATH</span></code> or
<code class="docutils literal notranslate"><span class="pre">CLASSPATH</span></code>. Other commands are used to call a separate compiled program, such as <code class="docutils literal notranslate"><span class="pre">ls</span></code>, <code class="docutils literal notranslate"><span class="pre">gcc</span></code>,
or <code class="docutils literal notranslate"><span class="pre">vim</span></code>. The code to execute these commands does not exist as a part of <code class="docutils literal notranslate"><span class="pre">bash</span></code>. Rather, these
are distinct programs and the code needs to be loaded into the new process.</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;unistd.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">int&nbsp;execl(const&nbsp;char&nbsp;*path,&nbsp;const&nbsp;char&nbsp;*arg0,&nbsp;...</span>&#160; <span class="pre">/*,</span> <span class="pre">(char&nbsp;*)0&nbsp;*/);</span></code></dt>
<dd>Executes the program identified by the exact&nbsp;path.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int&nbsp;execle(const&nbsp;char&nbsp;*path,&nbsp;const&nbsp;char&nbsp;*arg0,&nbsp;...</span>&#160; <span class="pre">/*,&nbsp;(char&nbsp;*)0,&nbsp;char*</span> <span class="pre">const&nbsp;envp[]*/);</span></code></dt>
<dd>Executes the program at&nbsp;path&nbsp;and set environment variables.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int&nbsp;execlp(const&nbsp;char&nbsp;*file,&nbsp;const&nbsp;char&nbsp;*arg0,&nbsp;...</span>&#160; <span class="pre">/*,&nbsp;(char&nbsp;*)0&nbsp;*/);</span></code></dt>
<dd>Looks up the program&nbsp;file&nbsp;in the current&nbsp;<code class="docutils literal notranslate"><span class="pre">PATH</span></code>.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int&nbsp;execv(const&nbsp;char&nbsp;*path,&nbsp;char&nbsp;*const&nbsp;argv[]);</span></code></dt>
<dd>Like&nbsp;execl, but command-line arguments are in an array.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int&nbsp;execve(const&nbsp;char&nbsp;*path,&nbsp;char&nbsp;*const&nbsp;argv[],&nbsp;char&nbsp;*const&nbsp;envp[]);</span></code></dt>
<dd>Like&nbsp;execle, but command-line arguments are in an array.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int&nbsp;execvp(const&nbsp;char&nbsp;*file,&nbsp;char&nbsp;*const&nbsp;argv[]);</span></code></dt>
<dd>Like&nbsp;execlp, but command-line arguments are in an array.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int&nbsp;fexecve(int&nbsp;fd,&nbsp;char&nbsp;*const&nbsp;argv[],&nbsp;char&nbsp;*const&nbsp;envp[]);</span></code></dt>
<dd>Executes the program stored in an open file handle&nbsp;fd.</dd>
</dl>
</div>
<p>Loading a new program is handled by the <code class="docutils literal notranslate"><span class="pre">exec()</span></code> system call, which can be invoked by a family of
C functions. The functions differ by how you pass the parameters. The <code class="docutils literal notranslate"><span class="pre">execl()</span></code>, <code class="docutils literal notranslate"><span class="pre">execle()</span></code>, and
<code class="docutils literal notranslate"><span class="pre">execlp()</span></code> functions take the command line arguments as additional function parameters, whereas
execv(), execve(), and execvp() require you to create a single array that contains all of the
arguments. The <code class="docutils literal notranslate"><span class="pre">execl()</span></code> and <code class="docutils literal notranslate"><span class="pre">execv()</span></code> functions expect that you provide the exact path to the
executable file, while <code class="docutils literal notranslate"><span class="pre">execlp()</span></code> and <code class="docutils literal notranslate"><span class="pre">execvp()</span></code> will look up the path for you. The <code class="docutils literal notranslate"><span class="pre">execle()</span></code>
and <code class="docutils literal notranslate"><span class="pre">execve()</span></code> functions allow you to specify a custom set of environment variables for the new
program. Finally, <code class="docutils literal notranslate"><span class="pre">fexecve()</span></code> allows you to pass an open file descriptor for the program instead
of the programs name or path. <a class="reference external" href="ProcessCycle.html#cl2-8">Code Listings 2.8</a> and <a class="reference external" href="ProcessCycle.html#cl2-9">2.9</a> show two different ways to
call the <code class="docutils literal notranslate"><span class="pre">ls</span></code> program to list files, one using <code class="docutils literal notranslate"><span class="pre">execl()</span></code> and the other using <code class="docutils literal notranslate"><span class="pre">execvp()</span></code>.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 2.8:</span>
<span class="cm"> Using execl() lists all parameters in one list and requires an exact path</span>
<span class="cm"> */</span>
<span class="cm">/* Create the child and run &#39;ls -l&#39; */</span>
<span class="kt">pid_t</span> <span class="n">child_pid</span> <span class="o">=</span> <span class="n">fork</span> <span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">exit</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="cm">/* exit if fork() failed */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">rc</span> <span class="o">=</span> <span class="n">execl</span> <span class="p">(</span><span class="s">&quot;/bin/ls&quot;</span><span class="p">,</span> <span class="s">&quot;ls&quot;</span><span class="p">,</span> <span class="s">&quot;-l&quot;</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="n">exit</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="cm">/* exit if exec fails */</span>
<span class="p">}</span>
<span class="cm">/* Make the parent wait for the first child */</span>
<span class="n">wait</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-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
18</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 2.9:</span>
<span class="cm"> Using execvp() puts command-line arguments in a vector and does a path lookup</span>
<span class="cm"> */</span>
<span class="cm">/* Set up all parameters for &#39;ls -l&#39; in a single vector */</span>
<span class="kt">char</span> <span class="o">*</span><span class="k">const</span> <span class="n">parameters</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="s">&quot;ls&quot;</span><span class="p">,</span> <span class="s">&quot;-l&quot;</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">};</span>
<span class="n">child_pid</span> <span class="o">=</span> <span class="n">fork</span> <span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">exit</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="cm">/* exit if fork() failed */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">rc</span> <span class="o">=</span> <span class="n">execvp</span> <span class="p">(</span><span class="s">&quot;ls&quot;</span><span class="p">,</span> <span class="n">parameters</span><span class="p">);</span>
<span class="n">exit</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="cm">/* exit if exec fails */</span>
<span class="p">}</span>
<span class="cm">/* Make the parent wait for the second child */</span>
<span class="n">wait</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>There are a couple of important points to note in this code. First, note that both calls to <code class="docutils literal notranslate"><span class="pre">ls</span></code>
will have the same three arguments (<code class="docutils literal notranslate"><span class="pre">argv[0]</span> <span class="pre">=</span> <span class="pre">&quot;ls&quot;</span></code>, <code class="docutils literal notranslate"><span class="pre">argv[1]</span> <span class="pre">=</span> <span class="pre">&quot;-l&quot;</span></code>, and <code class="docutils literal notranslate"><span class="pre">argv[2]</span> <span class="pre">=</span> <span class="pre">NULL</span></code>).
That is, the first parameter passed to <code class="docutils literal notranslate"><span class="pre">execl()</span></code> on line 12 of <a class="reference external" href="ProcessCycle.html#cl2-8">Code Listing 2.8</a> is not included in
the argument list as the child process receives it. The convention that <code class="docutils literal notranslate"><span class="pre">argv[0]</span></code> is the name of
the program arises from how programs like bash specify the remaining parameters to the <code class="docutils literal notranslate"><span class="pre">exec()</span></code> functions.</p>
<p>Second, observe that both versions use <code class="docutils literal notranslate"><span class="pre">NULL</span></code> to indicate the end of the arguments. In the case of
<code class="docutils literal notranslate"><span class="pre">execl()</span></code>, function takes a variable-length parameter list, so it relies on <code class="docutils literal notranslate"><span class="pre">NULL</span></code> to know when
it should stop looking for arguments. In the case of <code class="docutils literal notranslate"><span class="pre">execvp()</span></code>, the function expects exactly two
arguments, with the second being an array of unknown length.</p>
<p>Third, note that the first parameter of <code class="docutils literal notranslate"><span class="pre">execl()</span></code> must be an exact path to the location of the
executable file. If you call <code class="docutils literal notranslate"><span class="pre">execl()</span></code> with just <code class="docutils literal notranslate"><span class="pre">&quot;ls&quot;</span></code> instead of <code class="docutils literal notranslate"><span class="pre">&quot;/bin/ls&quot;</span></code>, then it will
look for an executable file in the current directory that is named <code class="docutils literal notranslate"><span class="pre">ls</span></code>. If the file does not
exist, the call to <code class="docutils literal notranslate"><span class="pre">execl()</span></code> will return a negative value to indicate an error. For the call to
<code class="docutils literal notranslate"><span class="pre">execvp()</span></code>, bash will look through the directories specified by the <code class="docutils literal notranslate"><span class="pre">PATH</span></code> environment variable
to try to find the executable file for you. If line 12 of <a class="reference external" href="ProcessCycle.html#cl2-8">Code Listing 2.8</a> used <code class="docutils literal notranslate"><span class="pre">execlp()</span></code> instead
of <code class="docutils literal notranslate"><span class="pre">execl()</span></code>, <code class="docutils literal notranslate"><span class="pre">bash</span></code> would perform a <code class="docutils literal notranslate"><span class="pre">PATH</span></code> lookup there, as well.</p>
<p>Finally, note that no code after a successful call to any of the <code class="docutils literal notranslate"><span class="pre">exec()</span></code> functions will execute
in the current process. In this case, <a class="reference external" href="ProcessCycle.html#cl2-8">Code Listing 2.8</a> line 13 and <a class="reference external" href="ProcessCycle.html#cl2-9">Code Listing 2.9</a> line 14 should
never be reached, so neither of the calls to <code class="docutils literal notranslate"><span class="pre">exit()</span></code> should happen. The reason is that <code class="docutils literal notranslate"><span class="pre">exec()</span></code>
<strong>replaces the current processs code, data, stack, and heap segments</strong>. Assuming the call to
<code class="docutils literal notranslate"><span class="pre">exec()</span></code> is successful, the child process will start over with a clean virtual memory instance;
none of the parent processs information is retained within the child process.</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>Always make sure to check the return values for both <code class="docutils literal notranslate"><span class="pre">fork()</span></code> and <code class="docutils literal notranslate"><span class="pre">exec()</span></code>. Most OS enforce a
limit on the number of processes that a single user can create; once you reach this limit,
<code class="docutils literal notranslate"><span class="pre">fork()</span></code> will fail. Similarly, if you make a mistake in the name of the file that you want to run
or you do not have permissions, <code class="docutils literal notranslate"><span class="pre">exec()</span></code> will fail and the child process will continue to execute
the current programs code. Failing to check these return values can lead to unexpected behavior.</p>
</div>
</div>
<div class="section" id="posix-spawn-interface">
<h2>2.5.3. POSIX Spawn Interface<a class="headerlink" href="ProcessCycle.html#posix-spawn-interface" title="Permalink to this headline"></a></h2>
<p>In recent years, the use of <code class="docutils literal notranslate"><span class="pre">fork()</span></code> has been criticized for a variety of reasons. For instance,
the implementation requirements of it are considered too slow and require too much power for very
small embedded computing systems (e.g., think of the “computers” in a car that operate the cruise
control or anti-lock breaking). Another problem is that calling <code class="docutils literal notranslate"><span class="pre">fork()</span></code> on a process with
multiple threads (see Chapter 7) can lead to inconsistent copies of the parent process; that is, the
thread that calls <code class="docutils literal notranslate"><span class="pre">fork()</span></code> might not have a completely accurate memory image, particularly in
<a class="reference internal" href="Glossary.html#term-multicore"><span class="xref std std-term">multicore</span></a> architectures. Lastly, the semantics of <code class="docutils literal notranslate"><span class="pre">fork()</span></code> have
become very complicated, as there are many special cases that must be handled, such as how to deal
with open files, timers, asynchronous I/O buffers, etc. <a class="footnote-reference" href="ProcessCycle.html#f14" id="id4">[1]</a></p>
<p>To address some of these criticisms, POSIX includes a new function interface, <code class="docutils literal notranslate"><span class="pre">posix_spawn()</span></code>.
This function takes multiple parameters, including the path to the executable and the <code class="docutils literal notranslate"><span class="pre">argv</span></code> and
<code class="docutils literal notranslate"><span class="pre">envp</span></code> arrays that would be passed into <code class="docutils literal notranslate"><span class="pre">execv()</span></code> or <code class="docutils literal notranslate"><span class="pre">execve()</span></code> functions. In addition,
<code class="docutils literal notranslate"><span class="pre">posix_spawn()</span></code> takes other parameters that can specify additional operations. These operations
give the programmer explicit control over the special cases mentioned above.</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;spawn.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">posix_spawn(pid_t</span> <span class="pre">*pid,</span> <span class="pre">const</span> <span class="pre">char</span> <span class="pre">*path,</span> <span class="pre">const</span> <span class="pre">posix_spawn_file_actions_t</span> <span class="pre">*file_actions,</span> <span class="pre">const</span> <span class="pre">posix_spawnattr_t</span> <span class="pre">*attrp,</span> <span class="pre">char</span> <span class="pre">*const</span> <span class="pre">argv[],</span> <span class="pre">char</span> <span class="pre">*const</span> <span class="pre">envp[]);</span></code></dt>
<dd>Create a new process and load the code identified by the path in a single call.</dd>
</dl>
</div>
<p><a class="reference external" href="ProcessCycle.html#cl2-10">Code Listing 2.10</a> shows how to use <code class="docutils literal notranslate"><span class="pre">posix_spawn()</span></code> to run an external program. In this case, the
<code class="docutils literal notranslate"><span class="pre">cksum</span></code> program is run on a CSV file, as specified in the <code class="docutils literal notranslate"><span class="pre">path</span></code> and <code class="docutils literal notranslate"><span class="pre">argv</span></code> arguments. The
childs process ID is returned through the call-by-reference parameter <code class="docutils literal notranslate"><span class="pre">&amp;child</span></code>. The <code class="docutils literal notranslate"><span class="pre">assert()</span></code>
is used here to confirm that the process was successfully spawned; <code class="docutils literal notranslate"><span class="pre">posix_spawn()</span></code> returns a
non-zero value if an error occurs at any point and the process was not successfully spawned.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 2.10:</span>
<span class="cm"> Using posix_spawn() to run a helper program instead of fork() and execv()</span>
<span class="cm"> */</span>
<span class="kt">pid_t</span> <span class="n">child</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">path</span> <span class="o">=</span> <span class="s">&quot;/usr/bin/cksum&quot;</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="o">=</span> <span class="p">{</span> <span class="s">&quot;cksum&quot;</span><span class="p">,</span> <span class="s">&quot;movies.csv&quot;</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">};</span>
<span class="cm">/* Spawn and run an external program in one step */</span>
<span class="n">assert</span> <span class="p">(</span><span class="n">posix_spawn</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">child</span><span class="p">,</span> <span class="n">path</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="n">argv</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">/* Make the parent wait for the child */</span>
<span class="n">wait</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
</div>
<div class="section" id="process-destruction">
<h2>2.5.4. Process Destruction<a class="headerlink" href="ProcessCycle.html#process-destruction" title="Permalink to this headline"></a></h2>
<p>A process can be terminated in a number of ways. Some methods of process termination are voluntary
in nature, such as when the code makes a call to <code class="docutils literal notranslate"><span class="pre">exit()</span></code>, <code class="docutils literal notranslate"><span class="pre">abort()</span></code>, or returns from
<code class="docutils literal notranslate"><span class="pre">main()</span></code>. Other methods are involuntary, such as when a process is killed after a segmentation
fault or similar exception. Regardless of what causes the process termination, the same set of
procedures are typically performed: open file handles are closed, the virtual memory space is
destroyed, the associated physical memory is reclaimed by the system, and any relevant data
structures in the kernel are cleaned up.</p>
<p>The preceding example also illustrates a key element about the timing of the destruction of
processes. Once a process calls <code class="docutils literal notranslate"><span class="pre">fork()</span></code> and creates a child process, the relative scheduling
between the parent and child is nondeterministic from the programmers perspective. The two
processes are scheduled independently by the OS running on that particular machine, and the
scheduling will be influenced by other processes running, as well. However, the parent can
temporarily pause its own execution by making a call to <code class="docutils literal notranslate"><span class="pre">wait()</span></code> or <code class="docutils literal notranslate"><span class="pre">waitpid()</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;sys/wait.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">pid_t&nbsp;wait(int&nbsp;*stat_loc);</span></code></dt>
<dd>Waits on all children, gets status information in&nbsp;stat_loc.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">pid_t&nbsp;waitpid(pid_t&nbsp;pid,&nbsp;int&nbsp;*stat_loc,&nbsp;int&nbsp;options);</span></code></dt>
<dd>Waits on a particular child process identified by&nbsp;pid.</dd>
</dl>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">wait()</span></code> system call will block the current process until all of its children have been
terminated. A call to <code class="docutils literal notranslate"><span class="pre">waitpid()</span></code> is similar, but it only waits for a single, identified child to
terminate. In the preceding example, the first child makes a call to <code class="docutils literal notranslate"><span class="pre">execl()</span></code> to run the <code class="docutils literal notranslate"><span class="pre">ls</span></code>
program. At approximately the same time, the parent process calls <code class="docutils literal notranslate"><span class="pre">wait(NULL)</span></code>. The
nondeterministic nature of scheduling means it is impossible to determine which happens first, but
the result is the same: the parent process will not proceed to the second call to <code class="docutils literal notranslate"><span class="pre">fork()</span></code> until
the first child process runs the <code class="docutils literal notranslate"><span class="pre">ls</span></code> program and terminates.</p>
<p>Note that there is no problem even if the child process terminates before the parent gets scheduled
to run. If all children have been terminated by the time a process calls <code class="docutils literal notranslate"><span class="pre">wait()</span></code>, then the parent
process will simply continue on without pausing. The only requirement for <code class="docutils literal notranslate"><span class="pre">wait()</span></code> is that the
parent cannot continue if there is at least one child process still trying to run.</p>
<p>The convention with C programs is to return an integer value from <code class="docutils literal notranslate"><span class="pre">main()</span></code> to indicate whether the
program completed successfully. The standard practice is to return 0 to indicate that no error
occurred, whereas a non-zero value typically indicates an error occurred in some way. When working
on the command-line, this value can be retrieved by printing the <code class="docutils literal notranslate"><span class="pre">bash</span></code> variable <code class="docutils literal notranslate"><span class="pre">$?</span></code>. In C
programs, this value can be retrieved through the <code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">*</span></code> parameter passed to <code class="docutils literal notranslate"><span class="pre">wait()</span></code> as shown
in <a class="reference external" href="ProcessCycle.html#cl2-11">Code Listing 2.11</a>.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl2-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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 2.11:</span>
<span class="cm"> Using wait() and WEXITSTATUS() to retrieve a process&#39;s return code</span>
<span class="cm"> */</span>
<span class="cm">/* Create the first child and run &#39;ls -l&#39; */</span>
<span class="kt">pid_t</span> <span class="n">child_pid</span> <span class="o">=</span> <span class="n">fork</span> <span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">exit</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="cm">/* exit if fork() failed */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">child_pid</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">exit</span> <span class="p">(</span><span class="mi">23</span><span class="p">);</span> <span class="cm">/* child process exits */</span>
<span class="cm">/* Make the parent wait to retrieve the return code*/</span>
<span class="kt">int</span> <span class="n">status</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">pid_t</span> <span class="n">exited</span> <span class="o">=</span> <span class="n">wait</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">status</span><span class="p">);</span>
<span class="cm">/* Make the parent print the child&#39;s exit code of 23 */</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;PID %d exited with code %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">exited</span><span class="p">,</span> <span class="n">WEXITSTATUS</span><span class="p">(</span><span class="n">status</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>The return value of the child process is shifted to the left when it is retrieved using <code class="docutils literal notranslate"><span class="pre">wait()</span></code>,
as the lower eight bits are used for other purposes. The <code class="docutils literal notranslate"><span class="pre">WEXITSTATUS()</span></code> macro corrects this bit
shifting to receive the actual return code from the child process.</p>
</div>
<table class="docutils footnote" frame="void" id="f14" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="ProcessCycle.html#id4">[1]</a></td><td>For a full description of the problems with <code class="docutils literal notranslate"><span class="pre">fork()</span></code>, see the paper: A. Baumann, J.
Appavoo, O. Krieger, and T. Roscoe, “A <code class="docutils literal notranslate"><span class="pre">fork()</span></code> in the road.” In Workshop on Hot Topics in Operating
Systems (HotOS 19). New York, NY: ACM, 2019.</td></tr>
</tbody>
</table>
<div
id="ProcessLifeSumm"
class="embedContainer"
data-exer-name="ProcessLifeSumm"
data-long-name="Process life cycle questions"
data-short-name="ProcessLifeSumm"
data-frame-src="../../../Exercises/Processes/ProcessLifeSumm.html?selfLoggingEnabled=false&amp;localMode=true&amp;module=ProcessCycle&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="7"
data-type="ka"
data-exer-id="">
<div class="center">
<div id="ProcessLifeSumm_iframe"></div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="mt-4 container center">
«&#160;&#160;<a id="prevmod1" href="Syscall.html">2.4. System Call Interface</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod1" href="UnixFile.html">2.6. The UNIX File Abstraction</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>