mirror of
https://github.com/yasuhirokimura/db18
synced 2026-06-08 18:29:23 +00:00
243 lines
10 KiB
HTML
243 lines
10 KiB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||
<title>Using dbstl in multithreaded applications</title>
|
||
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
|
||
<meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
|
||
<link rel="start" href="index.html" title="Berkeley DB Programmer's Reference Guide" />
|
||
<link rel="up" href="stl.html" title="Chapter 7. Standard Template Library API" />
|
||
<link rel="prev" href="stl_txn_usage.html" title="Using transactions in dbstl" />
|
||
<link rel="next" href="stl_primitive_rw.html" title="Working with primitive types" />
|
||
</head>
|
||
<body>
|
||
<div xmlns="" class="navheader">
|
||
<div class="libver">
|
||
<p>Library Version 18.1.40</p>
|
||
</div>
|
||
<table width="100%" summary="Navigation header">
|
||
<tr>
|
||
<th colspan="3" align="center">Using dbstl in multithreaded
|
||
applications</th>
|
||
</tr>
|
||
<tr>
|
||
<td width="20%" align="left"><a accesskey="p" href="stl_txn_usage.html">Prev</a> </td>
|
||
<th width="60%" align="center">Chapter 7. Standard Template Library API</th>
|
||
<td width="20%" align="right"> <a accesskey="n" href="stl_primitive_rw.html">Next</a></td>
|
||
</tr>
|
||
</table>
|
||
<hr />
|
||
</div>
|
||
<div class="sect1" lang="en" xml:lang="en">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h2 class="title" style="clear: both"><a id="stl_mt_usage"></a>Using dbstl in multithreaded
|
||
applications</h2>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>
|
||
Multithreaded use of dbstl must obey the following
|
||
guidelines:
|
||
</p>
|
||
<div class="orderedlist">
|
||
<ol type="1">
|
||
<li>
|
||
<p>
|
||
For a few non-standard platforms, you must first
|
||
configure dbstl for that platform, but usually the
|
||
configure script will detect the applicable thread
|
||
local storage (TLS) modifier to use, and then use it.
|
||
If no appropriate TLS is found, the pthread TLS API is
|
||
used.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
Perform all initializations in a single thread.
|
||
<code class="methodname">dbstl::dbstl_startup()</code>
|
||
should be called mutually exclusive in a single thread
|
||
before using dbstl. If dbstl is used in only a single
|
||
thread, this function does not need to be called.
|
||
</p>
|
||
<p>
|
||
If necessary, callback functions for a complex type
|
||
T must be registered to the singleton of
|
||
DbstlElemTraits<T> before any container related
|
||
to T (for example,
|
||
<code class="literal">db_vector<T></code>), is used,
|
||
and certain isolation may be required among multiple
|
||
threads. The best way to do this is to register all
|
||
callback function pointers into the singleton in a
|
||
single thread before making use of the containers.
|
||
</p>
|
||
<p>
|
||
All container cursor open flags and auto commit
|
||
transaction begin/commit flags must be set in a single
|
||
thread before storing objects into or reading objects
|
||
from the container.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
Environment and database handles can optionally be
|
||
shared across threads. If handles are shared, they
|
||
must be registered in each thread that is using the
|
||
handle (either directly, or indirectly using the
|
||
containers that own the handles). You do this using
|
||
the <code class="function">dbstl::register_db()</code> and
|
||
<code class="function">dbstl::register_db_env()</code>
|
||
functions. Note that these functions are not necessary
|
||
if the current thread called
|
||
<code class="function">dbstl::open_db()</code> or
|
||
<code class="function">dbstl::open_env()</code> for the
|
||
handle that is being shared. This is because the open
|
||
functions automatically register the handle for you.
|
||
</p>
|
||
<p>
|
||
Note that the get/set functions that provide access
|
||
to container data members are not mutex-protected
|
||
because these data members are supposed to be set only
|
||
once at container object initialization. Applications
|
||
wishing to modify them after initialization must
|
||
supply their own protection.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
While container objects can be shared between
|
||
multiple threads, iterators and transactions can not
|
||
be shared.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
Set the <span class="bold"><strong>directdb_get</strong></span> parameter of the
|
||
container <code class="methodname">begin()</code> method to
|
||
<code class="literal">true</code> in order to guarantee that
|
||
referenced key/data pairs are always obtained from the
|
||
database and not from an iterator's cached value.
|
||
(This is the default behavior.) You should do this
|
||
because otherwise a rare situation may occur. Given
|
||
db_vector_iterator i1 and i2 used in the same
|
||
iteration, setting *i1 = new_value will not update i2,
|
||
and *i2 will return the original value.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
If using a CDS database, only const iterators or
|
||
read-only non-const iterators should be used for read
|
||
only iterations. Otherwise, when multiple threads try
|
||
to open read-write iterators at the same time,
|
||
performance is greatly degraded because CDS only
|
||
supports one write cursor open at any moment. The use
|
||
of read-only iterators is good practice in general
|
||
because dbstl contains internal optimizations for
|
||
read-only iterators.
|
||
</p>
|
||
<p>
|
||
To create a read-only iterator, do one of the
|
||
following:
|
||
</p>
|
||
<div class="itemizedlist">
|
||
<ul type="disc">
|
||
<li>
|
||
<p>
|
||
Use a <code class="literal">const</code> reference to
|
||
the container object, then call the
|
||
container's <code class="methodname">begin()</code>
|
||
method using the const reference, and then
|
||
store the return value from the
|
||
<code class="methodname">begin()</code> method in
|
||
a
|
||
<code class="methodname">db_vector::const_iterator</code>.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
If you are using a non-const container
|
||
object, then simply pass
|
||
<code class="literal">true</code> to the <span class="bold"><strong>readonly</strong></span> parameter
|
||
of the non-const
|
||
<code class="methodname">begin()</code> method.
|
||
</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
When using DS, CDS or TDS, enable the locking
|
||
subsystem by passing the <a href="../api_reference/C/envopen.html#envopen_DB_INIT_LOCK" class="olink">DB_INIT_LOCK</a> flag to
|
||
<code class="methodname">DbEnv::open()</code>.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
Perform portable thread synchronization within a
|
||
process by calling the following functions. These are
|
||
all global functions in the "dbstl" name space:
|
||
</p>
|
||
<table class="simplelist" border="0" summary="Simple list">
|
||
<tr>
|
||
<td>
|
||
<code class="function">db_mutex_t alloc_mutex();</code>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<code class="function">int lock_mutex(db_mutex_t);</code>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<code class="function">int unlock_mutex(db_mutex_t);</code>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<code class="function">void free_mutex(db_mutex_t);</code>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
<p>
|
||
These functions use an internal dbstl environment's
|
||
mutex functionality to synchronize. As a result, the
|
||
synchronization is portable across all platforms
|
||
supported by Berkeley DB.
|
||
</p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
<p>
|
||
The <code class="classname">WorkerThread</code> class provides
|
||
example code demonstrating the use of dbstl in multi-threaded
|
||
applications. You can find this class implemented in the dbstl
|
||
test suite.
|
||
</p>
|
||
</div>
|
||
<div class="navfooter">
|
||
<hr />
|
||
<table width="100%" summary="Navigation footer">
|
||
<tr>
|
||
<td width="40%" align="left"><a accesskey="p" href="stl_txn_usage.html">Prev</a> </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="u" href="stl.html">Up</a>
|
||
</td>
|
||
<td width="40%" align="right"> <a accesskey="n" href="stl_primitive_rw.html">Next</a></td>
|
||
</tr>
|
||
<tr>
|
||
<td width="40%" align="left" valign="top">Using transactions in dbstl </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="h" href="index.html">Home</a>
|
||
</td>
|
||
<td width="40%" align="right" valign="top"> Working with primitive types </td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</body>
|
||
</html>
|