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

502 lines
No EOL
35 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>9.5. Timing in Distributed Environments &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. Reliable Data Storage and Location" href="DistDataStorage.html" />
<link rel="prev" title="4. Limits of Parallelism and Scaling" href="Scaling.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="DistTiming.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="DistTiming.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/DistTiming.rst"
target="_blank" rel="nofollow">Show Source</a></li>
</ul>
</nav>
<div class="container center">
«&#160;&#160;<a id="prevmod" href="Scaling.html">9.4. Limits of Parallelism and Scaling</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod" href="DistDataStorage.html">9.6. Reliable Data Storage and Location</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 = "DistTiming";ODSA.SETTINGS.MODULE_LONG_NAME = "Timing in Distributed Environments";ODSA.SETTINGS.MODULE_CHAPTER = "Parallel and Distributed Systems"; ODSA.SETTINGS.BUILD_DATE = "2021-06-01 15:31:51"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="timing-in-distributed-environments">
<h1>9.5. Timing in Distributed Environments<a class="headerlink" href="DistTiming.html#timing-in-distributed-environments" title="Permalink to this headline"></a></h1>
<p>As we have noted in this and previous chapters, concurrency and parallelism
introduce an element of nondeterminism that can complicate the design,
implementation, and execution of software. Once multiple threads or processes
are running independently, the order in which key events are processed can
become unpredictable. However, as individual computers possess a single,
universal system clock that can be shared, it would be straightforward to use
synchronization primitives to keep an orderly log of key events, as shown in
<a class="reference external" href="DistTiming.html#cl9-8">Code Listing 9.8</a>.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl9-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 9.8:</span>
<span class="cm"> Sample routine for atomic log file append </span>
<span class="cm"> */</span>
<span class="kt">void</span>
<span class="nf">append_log</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">message</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* Uses a global variable for locking the log */</span>
<span class="n">pthread_mutex_lock</span> <span class="p">(</span><span class="n">log_lock</span><span class="p">);</span>
<span class="k">struct</span> <span class="n">timespec</span> <span class="n">current_time</span><span class="p">;</span>
<span class="n">clock_gettime</span> <span class="p">(</span><span class="n">CLOCK_MONOTONIC</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">current_time</span><span class="p">);</span>
<span class="kt">FILE</span> <span class="o">*</span><span class="n">file</span> <span class="o">=</span> <span class="n">fopen</span> <span class="p">(</span><span class="n">SYSTEM_LOG_FILE</span><span class="p">,</span> <span class="s">&quot;a&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">file</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fprintf</span> <span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s">&quot;%lld.%09ld %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="p">(</span><span class="kt">long</span> <span class="kt">long</span><span class="p">)</span> <span class="n">current_time</span><span class="p">.</span><span class="n">tv_sec</span><span class="p">,</span>
<span class="n">current_time</span><span class="p">.</span><span class="n">tv_nsec</span><span class="p">,</span> <span class="n">message</span><span class="p">);</span>
<span class="n">fclose</span> <span class="p">(</span><span class="n">file</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">pthread_mutex_unlock</span> <span class="p">(</span><span class="n">log_lock</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p>The challenge of logging events in distributed environments is much more
difficult, as there is no universal clock that can be used. Each system has its
own internal system clock, but these clocks may be misconfigured or naturally
drift over time. This problem could potentially be addressed by synchronizing
the system clocks to agree on the time. However, as the system becomes larger
and the physical distance between nodes increases, delays in the network can
become unpredictable and too difficult to counteract. The solution in that case
would be to give up on trying to synchronize the clocks and focus on a coherent
ordering of events instead.</p>
<div class="section" id="clock-synchronization">
<h2>9.5.1. Clock Synchronization<a class="headerlink" href="DistTiming.html#clock-synchronization" title="Permalink to this headline"></a></h2>
<div class="figure mb-2 align-right" id="id2" style="width: 23%">
<span id="ntpsequence"></span><a class="reference internal image-reference" href="_images/CSF-Images.9.7.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Sequence of messages and events in NTP" src="_images/CSF-Images.9.7.png" style="width: 90%;" /></a>
<p class="caption align-center px-3"><span class="caption-text"> Figure 9.5.1: Sequence of messages and events in NTP</span></p>
</div>
<p>One approach to solving the timing problem in distributed environments is to
synchronize the clocks on all nodes with a centralized server.
<a href="DistTiming.html#ntpsequence">Figure 9.5.1</a> shows the exchange of messages in the
<a class="reference internal" href="Glossary.html#term-network-time-protocol"><span class="xref std std-term">Network Time Protocol (NTP)</span></a>, one solution built on this idea. In NTP, each
node will occasionally poll the server, keeping track of the times when certain events
occur. Specifically, the client records $T_1$ as the time that it sent the poll
message. The server received the message at $T_2$ according to its internal clock,
sending the response back at time $T_3$ (according to the servers clock). The
client then records $T_4$ as the time that it received the response from the
server. Based on this information, the client would calculate two values:</p>
<center>
<span class="math inline">$\large \mbox{offset} =
\displaystyle\frac{(T_2 - T_1) + (T_3 - T_4)}{2}$</span><br /><br />
<span class="math inline">$\large \mbox{delay} =
(T_4 - T_1) - (T_3 - T_2)$</span>
</center>
<br /><p>The delay is used to eliminate the time that it takes for the messages to travel
through the network from consideration. The offset is used to detect the clock
skew between the nodes. For instance, assume $T_1 = 20$, $T_2 = 30$, $T_3 = 32$,
and $T_4 = 46$. Then the offset would be calculated as $(10 - 14)/2 = -2$, and
the delay would be $26 - 2 = 24$. The message from client to server was measured
as taking 10 time units, whereas the response took longer (14 time units). One
possible cause is that the clients clock is ahead of the servers clock. If the
clients clock was adjusted back so that $T_1 = 18$ and $T_4 = 44$, then the
offset would be 0, as the two messages would be measured as taking 12 time units
in each direction. The client passes the offset and delay values, along with
previous measurements, through a suite of protocols to filter and select the
most accurate values. The client then combines these <em>survivor</em> offsets to
adjust the system clock time and frequency. The protocol can then be repeated
until the offset is sufficiently small. <a class="footnote-reference" href="DistTiming.html#f50" id="id1">[1]</a></p>
</div>
<div class="section" id="logical-clocks-and-lamport-timestamps">
<h2>9.5.2. Logical Clocks and Lamport Timestamps<a class="headerlink" href="DistTiming.html#logical-clocks-and-lamport-timestamps" title="Permalink to this headline"></a></h2>
<p>As systems grow larger and nodes increase in physical distance, trying to
synchronize the internal clocks of nodes in the system becomes unmanageable. The
number of messages needed for protocols like NTP impose a significant burden on
the network that would interfere with other work. An alternative approach is to
establish a reasonable understanding of the sequence of events using
<a class="reference internal" href="Glossary.html#term-logical-clock"><span class="xref std std-term">logical clocks</span></a>. A logical clock uses messages, not real time
measurements, to track the relative, logical ordering of events. These messages
are <a class="reference internal" href="Glossary.html#term-asynchronous"><span class="xref std std-term">asynchronous</span></a>, in the sense that there are no timing guarantees;
network and other processing delays introduce random timing differences between
when a message is sent and received.</p>
<p><a class="reference internal" href="Glossary.html#term-lamport-timestamp"><span class="xref std std-term">Lamport timestamps</span></a> are a simple approach to logical clocks. Each process
(a task running on a separate node) maintains an internal counter of events that
it experiences. These events could be a local action or computational result
that is relevant to the system as a whole. Whenever a local event occurs, or a
process sends or receives a message, this internal counter is incremented. When
processes send messages, they append their counter. Given their distributed
nature, processes can only observe local events and messages they send or
receive; they cannot be aware of messages received by other processes or events
that occur elsewhere in the system. <a class="reference external" href="DistTiming.html#cl9-9">Code Listing 9.9</a> shows the basic
algorithm for receiving a message with a Lamport timestamp. The messages
timestamp is compared with the local processs counter, and the local timestamp
is updated to be the greater of the two. The timestamp is then incremented,
keeping track of the event of receiving the message.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl9-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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 9.9:</span>
<span class="cm"> Reading a message from a socket with a Lamport timestamp attached</span>
<span class="cm"> */</span>
<span class="kt">ssize_t</span> <span class="n">bytes</span> <span class="o">=</span> <span class="n">read</span> <span class="p">(</span><span class="n">socketfd</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">message</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">message</span><span class="p">));</span>
<span class="cm">/* Update local timestamp if message has greater value */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">message</span><span class="p">.</span><span class="n">timestamp</span> <span class="o">&gt;</span> <span class="n">local_timestamp</span><span class="p">)</span>
<span class="n">local_timestamp</span> <span class="o">=</span> <span class="n">message</span><span class="p">.</span><span class="n">timestamp</span><span class="p">;</span>
<span class="cm">/* Increment local timestamp */</span>
<span class="n">local_timestamp</span><span class="o">++</span><span class="p">;</span>
</pre></div>
</td></tr></table></div>
<div class="figure mb-2 align-right" id="id3" style="width: 45%">
<span id="logicalclocks"></span><a class="reference internal image-reference" href="_images/CSF-Images.9.8.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Events and messages using logical clocks" src="_images/CSF-Images.9.8.png" style="width: 95%;" /></a>
<p class="caption align-center px-3"><span class="caption-text"> Figure 9.5.2: Events and messages using logical clocks</span></p>
</div>
<p>As an example, consider a cloud computing system that provides
Internet-accessible data storage service. <a href="DistTiming.html#logicalclocks">Figure 9.5.2</a>
shows a sample sequence of events that may occur; the numbers in brackets denote
the Lamport timestamps. Process A provides an interface for users and receives a
request for the files “foo” and “zoo”; this request constitutes a local event
for A, which has the timestamp 1. A then sends a message to process B (timestamp
2) and another to process C (timestamp 3); receiving these messages occur at
times 3 and 4, respectively. Note that process B has no knowledge of the message
sent to C, so Bs local timestamp only reflects its knowledge of the message it
received.</p>
<p>After receiving their messages from process A, processes B and C concurrently
load the two files requested. C sends the contents of “zoo” to B (timestamp 6)
and B receives this message. Note that Bs timestamp jumps from 4 to 7 when this
happens, reflecting the timestamp it observes in the message from C. B then
merges the files (timestamp 8) and sends the result to A.</p>
<p>With logical clocks, it is critical to note that an earlier timestamp does not
necessarily guarantee that an event occurred before one with a later timestamp.
Consider process Bs perspective in <a href="DistTiming.html#logicalclocks">Figure 9.5.2</a>. B
observes the local logical ordering of events at timestamps 3, 4, and 7.
However, B cannot know if “foo” was loaded before or after “zoo.” In fact, B
cannot even know that the message it received from A was sent before the message
from A to C. B can only observe the logical ordering of events within its own
time line. If B later receives a message from A with a timestamp greater than
11, it knows that message comes after the message when it sent foo+zoo to A.
However, if Bs next interaction with C is receiving a message with timestamp
11, B cannot determine precisely when this message was sent; its possible that
C experienced several events before B merged the files at timestamp 8.</p>
<p>In summary, logical clocks provide a mechanism for processes to exchange
information about the relative ordering of events based on their perspectives.
If processes A and B exchange messages back and forth, they can determine the
relative ordering of these events. Once a third process C starts exchanging
messages with A, process A will be able to determine the relative ordering of
these messages, but neither B nor C would have the full view of the exchanges.</p>
</div>
<div class="section" id="vector-clocks">
<h2>9.5.3. Vector Clocks<a class="headerlink" href="DistTiming.html#vector-clocks" title="Permalink to this headline"></a></h2>
<p><a href="DistTiming.html#logicalclocks">Figure 9.5.2</a> illustrates one of the shortcomings of
logical clocks with Lamport timestamps. Note that process As timeline jumps
from timestamp 3 to the message it receives from B with timestamp 9. Given only
this information, process A could not distinguish this sequence of events from a
different timeline in which B experienced only local events. That is, the
timestamp that process A observes in the message from B does not even provide
assurance that B received the original message from A, nor does it suggest that
B has been communicating with C. Lamport timestamps alone do not provide
sufficient information to distinguish these scenarios.</p>
<div class="figure mb-2 align-right" id="id4" style="width: 50%">
<span id="vectorclocks"></span><a class="reference internal image-reference" href="_images/CSF-Images.9.9.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="The events of :num:`Figure #LogicalClocks` with vector clocks" src="_images/CSF-Images.9.9.png" style="width: 95%;" /></a>
<p class="caption align-center px-3"><span class="caption-text"> Figure 9.5.3: The events of <a href="DistTiming.html#logicalclocks">Figure 9.5.2</a> with vector clocks</span></p>
</div>
<p><a class="reference internal" href="Glossary.html#term-vector-clock"><span class="xref std std-term">Vector clocks</span></a> extend the basic idea of logical clocks with more
information to address this problem. Whereas logical clocks kept only a single
counter to establish the relative ordering of events, vector clocks use one
counter per process. When a process sends a message, it appends the vector of
counters from its perspective, implicitly acknowledging its understanding of the
other processs timestamps. <a href="DistTiming.html#vectorclocks">Figure 9.5.3</a> illustrates the
same sequence of events from <a href="DistTiming.html#logicalclocks">Figure 9.5.2</a>, using vector
clocks instead of Lamport timestamps. When process B receives the first message
from A, B increments its own counter in the vector.</p>
<p><a href="DistTiming.html#vectorclocks">Figure 9.5.3</a> illustrates a key strength of vector clocks
with the message from process C to B containing the contents of zoo. This
message contains the vector [3,0,3], indicating that C believes process As
timestamp is at least 3. But B had previously received the vector [2,0,0] from
process A, so process B knows that As message to C was sent after As message
to B. Note, though, that process B cannot be certain about the order of events
that C experienced. That is, the vector [2,0,0] was A stating it believed Cs
timestamp was 0. The best that process B can state is that the message it
received from C had been sent after A sent the first message to B. For an
asynchronous system, this claim is the best that can be made.</p>
<table class="docutils footnote" frame="void" id="f50" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="DistTiming.html#id1">[1]</a></td><td>For more specifics on how the offset and delay are used, see the NTP
homepage available at <code class="docutils literal notranslate"><span class="pre">https://www.eecis.udel.edu/~mills/ntp/html/warp.html</span></code>.</td></tr>
</tbody>
</table>
<div
id="TimingSumm"
class="embedContainer"
data-exer-name="TimingSumm"
data-long-name="Distributed timing questions"
data-short-name="TimingSumm"
data-frame-src="../../../Exercises/ParallelDistributed/TimingSumm.html?selfLoggingEnabled=false&amp;localMode=true&amp;module=DistTiming&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="TimingSumm_iframe"></div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="mt-4 container center">
«&#160;&#160;<a id="prevmod1" href="Scaling.html">9.4. Limits of Parallelism and Scaling</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod1" href="DistDataStorage.html">9.6. Reliable Data Storage and Location</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>