155 lines
9.8 KiB
HTML
155 lines
9.8 KiB
HTML
<!-- BeginDsi "dsi/head.html" -->
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<title>Embedthis Appweb 4.3.4 Documentation</title>
|
|
<meta name="keywords" content="embedded web server, web server software, embedded HTTP, application web server,
|
|
embedded server, small web server, HTTP server, library web server, library HTTP, HTTP library" />
|
|
<meta name="description" content="Embedthis Sofware provides commercial and open source embedded web servers for
|
|
devices and applications." />
|
|
<meta name="robots" content="index,follow" />
|
|
<link href="../../doc.css" rel="stylesheet" type="text/css" />
|
|
<link href="../../print.css" rel="stylesheet" type="text/css" media="print"/>
|
|
<!--[if IE]>
|
|
<link href="../../iehacks.css" rel="stylesheet" type="text/css" />
|
|
<![endif]-->
|
|
<link href="http://www.google.com/cse/style/look/default.css" type="text/css" rel="stylesheet" />
|
|
</head>
|
|
|
|
<body>
|
|
<div class="top">
|
|
<a class="logo" href="http://appwebserver.org/"> </a>
|
|
<div class="topRight">
|
|
<div class="search">
|
|
<div id="cse-search-form"></div>
|
|
<div class="version">Embedthis Appweb 4.3.4</div>
|
|
</div>
|
|
</div>
|
|
<div class="crumbs">
|
|
<a href="../../index.html">Home</a>
|
|
<!-- EndDsi -->
|
|
> <a href="index.html">Programmers Reference</a> > <b>Architecture</b>
|
|
</div>
|
|
</div>
|
|
<div class="content">
|
|
<div class="contentRight">
|
|
<h1>Quick Nav</h1>
|
|
<ul>
|
|
<li><a href="#overview">Overview</a></li>
|
|
<li><a href="#dispatchers">Dispatchers</a></li>
|
|
<li><a href="#multithreaded">Multithreaded</a></li>
|
|
<li><a href="#modules">Modules</a></li>
|
|
<li><a href="#locking">Locking</a></li>
|
|
</ul>
|
|
<h1>See Also</h1>
|
|
<ul>
|
|
<li><a href="architecture.html">Appweb Architecture</a></li>
|
|
<li><a href="memory.html">MPR Memory Allocator</a></li>
|
|
<li><a href="../../guide/appweb/overview.html">User Guide Overview</a></li>
|
|
<li><a href="../../guide/appweb/users/authentication.html">Authorization</a></li>
|
|
<li><a href="../../guide/appweb/users/configuration.html">Configuration</a></li>
|
|
<li><a href="../../guide/appweb/users/configuration.html#directives">Configuration Directives</a></li>
|
|
<li><a href="../../guide/appweb/users/stages.html">Pipeline Stages</a></li>
|
|
<li><a href="../../guide/appweb/users/client.html">HTTP Client</a></li>
|
|
<li><a href="../../guide/appweb/users/modules.html">Loadable Modules</a></li>
|
|
<li><a href="../../guide/appweb/users/ports.html">Ports and Binding</a></li>
|
|
<li><a href="../../guide/appweb/users/ssl.html">Secure Sockets Layer</a></li>
|
|
<li><a href="../../guide/appweb/users/vhosts.html">Virtual Hosts</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="contentLeft">
|
|
<h1>Multithreaded Programming</h1>
|
|
<a id="overview"></a>
|
|
<h2>Overview</h2>
|
|
<p>Programming in a multithreaded environment can be difficult. Sometimes programming errors are timing related
|
|
as multiple threads interact. Multithread locks can become tangled and bugs can be difficult to reproduce.
|
|
To alleviate these problems and
|
|
enable the benefits of a multi-threaded core, Appweb provides a suite of facilities to make multithreaded
|
|
programming easier, more reliable, and more efficient.</p>
|
|
<h3>The Problem of Multithreaded I/O Events</h3>
|
|
<p>A particular thorny issue in multithreaded servers, is how to handle I/O without consuming a thread for
|
|
each request. It is not practical to dedicate a thread to each HTTP request. A single browser will often
|
|
send 6-10 simultaneous requests. If each request consumed a thread for the duration, the web server would
|
|
quickly consume too many threads and system performance would greatly suffer. </p>
|
|
<p>One solution is to use a thread pool. This allows a request to borrow a thread from a thread pool while
|
|
the request is active and return the thread when it cannot immediately continue with servicing the request.
|
|
A thread may
|
|
not be able to continue because it is waiting for I/O from the client, or waiting for I/O to the client to
|
|
drain over the network. Returning the thread to the pool allows other requests to use the thread while the
|
|
first request is waiting for network I/O. When the network is ready, a thread can be obtained from the pool
|
|
and the original request can continue. For this to work, an efficient network event service is
|
|
essential. Appweb uses such a thread pool and event service to efficiently manage thread resources. </p>
|
|
|
|
<p>However, this use of such an event service and thread pool raises another problem: races between the
|
|
foreground request thread and the background async I/O event thread. It is easy for these two threads to
|
|
simultaneously interact and corrupt critical data structures. A typical solution is to use multithread
|
|
locks to serialize access to such data, but this is a crude solution and often leads to brittle applications.
|
|
Appweb has a better solution that effectively serializes all activity for a request: per-request
|
|
event dispatchers.</p>
|
|
<a id="dispatchers"></a>
|
|
<h3>Event Dispatchers</h3>
|
|
<p>The Multithreaded Portable Runtime (MPR) used by Appweb has a facility called Event Dispatchers. These
|
|
are event queues on which all I/O and other event activity for a request can be queued and serviced.
|
|
Each request has its own dispatcher and so events for a request are serialized. When a network I/O event
|
|
is received by Appweb for a request, an event is queued on the request's dispatcher. If the request is
|
|
currently active (using a thread from the thread pool), the event is queued and no further action is taken.
|
|
When the request has finished its current activity, it will service events on its dispatcher queue and
|
|
eventually service the I/O event. If the request is currently idle, a thread is assigned from the thread
|
|
pool for the request, and the thread is resumed to service the request's dispatcher queue. This greatly
|
|
simplifies Appweb as all activity for a request is thus serialized via the dispatcher queue.</p>
|
|
<a id="multithreaded"></a>
|
|
<h3>Multithreaded Appweb</h3>
|
|
<p>By using request dispatchers, Appweb serializes all request activity, yet it can support many
|
|
simultaneous requests due to its multithreaded core. Appweb efficiently utilizes thread resources by using
|
|
a thread pool and not dedicating threads permanently to requests. Threads are temporarily assigned
|
|
only as required by active requests.</p>
|
|
<a id="modules"></a>
|
|
<h3>Modules</h3>
|
|
<p>Appweb can be extended by writing loadable modules. Modules can add request handlers, pipeline filters,
|
|
or network connectors. All module code can rely on the fact that request activity will be serialized and
|
|
no locking is required to serialize I/O activity. Consequently, most module code can be effectively
|
|
single-threaded.</p>
|
|
<p>Appweb can also be extended via Embedded Server Pages applications. These are loadable ESP web pages,
|
|
and ESP Model-View-Controller applications. These too can rely on the fact that request activity is serialized
|
|
and locking primitives are typically not required. ESP code can thus be simple,
|
|
single-threaded application code.</p>
|
|
|
|
<a id="locking"></a>
|
|
<h3>Locking</h3>
|
|
<p>If you have a requirement for a data structure that will be accessed and manipulated simultaneously
|
|
by multiple threads, the MPR provides a suite of locking primitives. See
|
|
<a href="../../api/mpr.html#group___mpr_synch">MprSynch</a> for the MPR Multithreaded Synchronization Services.</p>
|
|
</div>
|
|
</div>
|
|
<!-- BeginDsi "dsi/bottom.html" -->
|
|
<div class="bottom">
|
|
<p class="footnote">
|
|
<a href="../../product/copyright.html" >© Embedthis Software LLC, 2003-2013.
|
|
All rights reserved. Embedthis, Appweb, ESP, Ejscript and Embedthis GoAhead are trademarks of Embedthis Software LLC.</a>
|
|
</p>
|
|
</div>
|
|
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
|
|
<script type="text/javascript">
|
|
google.load('search', '1', {language : 'en'});
|
|
google.setOnLoadCallback(function() {
|
|
var customSearchControl = new google.search.CustomSearchControl(
|
|
'000262706376373952077:1hs0lhenihk');
|
|
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
|
|
var options = new google.search.DrawOptions();
|
|
options.enableSearchboxOnly("http://appwebserver.org/search.html");
|
|
customSearchControl.draw('cse-search-form', options);
|
|
}, true);
|
|
</script>
|
|
<script type="text/javascript">
|
|
var _gaq = _gaq || [];
|
|
_gaq.push(['_setAccount', 'UA-179169-2']);
|
|
_gaq.push(['_trackPageview']);
|
|
(function() {
|
|
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
|
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
|
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|