ibm-information-center/dist/eclipse/plugins/i5OS.ic.apis_5.4.0.1/users_64.htm

287 lines
12 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Copyright" content="Copyright (c) 2006 by IBM Corporation">
<title>pthread_mutex_trylock()--Lock Mutex with No Wait</title>
<!-- All rights reserved. Licensed Materials Property of IBM -->
<!-- US Government Users Restricted Rights -->
<!-- Use, duplication or disclosure restricted by -->
<!-- GSA ADP Schedule Contract with IBM Corp. -->
<!-- Begin Header Records ========================================== -->
<!-- NETMG2 SCRIPT A converted by B2H R4.1 (346) (CMS) by HOLTJM at -->
<!-- RCHVMW2 on 29 Jan 1999 at 10:01:37 -->
<!--File Edited November 2001 -->
<!--End Header Records -->
<link rel="stylesheet" type="text/css" href="../rzahg/ic.css">
</head>
<body>
<!-- Java sync-link -->
<script language="Javascript" src="../rzahg/synch.js" type="text/javascript">
</script>
<a name="Top_Of_Page"></a>
<h2>pthread_mutex_trylock()--Lock Mutex with No Wait</h2>
<div class="box" style="width: 60%;">
<br>
&nbsp;&nbsp;Syntax:
<pre> #include &lt;pthread.h&gt;
int pthread_mutex_trylock(pthread_mutex_t *mutex); </pre>
&nbsp;&nbsp;Service Program Name: QP0WPTHR<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Default Public Authority: *USE <br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Threadsafe: Yes<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Signal Safe: Yes<br>
<!-- iddvc RMBR -->
<br>
</div>
<p>The <strong>pthread_mutex_trylock</strong>() function attempts to acquire ownership of the mutex specified without blocking the calling thread. If the mutex is currently locked by another thread, the call to pthread_mutex_trylock() returns an error of EBUSY.</p>
<p>A failure of EDEADLK indicates that the mutex is already held by the calling thread.</p>
<p>Mutex initialization using the <strong>PTHREAD_MUTEX_INITIALIZER</strong> does not immediately initialize the mutex. Instead, on first use, <strong>pthread_mutex_timedlock_np</strong>() or <strong>pthread_mutex_lock</strong>() or <strong>pthread_mutex_trylock</strong>() branches into a slow path and causes the initialization of the mutex. Because a mutex is not just a simple memory object and requires that some resources be allocated by the system, an attempt to call <strong>pthread_mutex_destroy</strong>() or <strong>pthread_mutex_unlock</strong>() on a mutex that was statically initialized using <strong>PTHREAD_MUTEX_INITIALIZER</strong> and was not yet locked causes an <strong>EINVAL</strong> error.</p>
<p>The maximum number of recursive locks by the owning thread is 32,767. When this number is exceeded, attempts to lock the mutex return the <strong>ERECURSE</strong> error.</p>
<br>
<h3>Mutex Types</h3>
<p>A normal mutex cannot be locked repeatedly by the owner. Attempts by a thread to relock an already held mutex, or to lock a mutex that was held by another thread when that thread terminated, cause a deadlock condition.</p>
<p>A recursive mutex can be locked repeatedly by the owner. The mutex does not become unlocked until the owner has called <strong>pthread_mutex_unlock</strong>() for each successful lock request that it has outstanding on the mutex.</p>
<p>An errorcheck mutex checks for deadlock conditions that occur when a thread relocks an already held mutex. If a thread attempts to relock a mutex that it already holds, the lock request fails with the <strong>EDEADLK</strong> error.</p>
<p>An ownerterm mutex is an i5/OS extension to the errorcheck mutex type. An ownerterm mutex checks for deadlock conditions that occur when a thread relocks an already held mutex. If a thread attempts to relock a mutex that it already holds, the lock request fails with the <strong>EDEADLK</strong> error. An ownerterm mutex also checks for deadlock conditions that occur when a thread attempts to lock a mutex that was held by another thread when that thread terminated (an orphaned mutex). If a thread attempts to lock an orphaned mutex, the lock request fails with the <strong>EOWNERTERM</strong> error.</p>
<p>When a thread terminates while holding a mutex lock on a normal or errorcheck mutex, other threads that wait for that mutex will block forever. The pthreads run-time simulates the deadlock that has occurred in your application. When you are attempting to debug these deadlock scenarios, the CL command WRKJOB, option 20, shows the thread as in a condition wait. Displaying the call stack shows that the function <strong>deadlockOnOrphanedMutex</strong> is in the call stack.</p>
<p>When a thread attempts to acquire a normal mutex that it already holds, the thread will block forever. The pthreads run-time simulates the deadlock that has occurred in your application. When you are attempting to debug these deadlock scenarios, the CL command WRKJOB, option 20, shows the thread as in a condition wait. Displaying the call stack shows that the function <strong>deadlockOnAlreadyHeldMutex</strong> is in the call stack.</p>
<p>To change these behaviors, use an errorcheck or ownerterm mutex type.</p>
<br>
<h3>Authorities and Locks</h3>
<p>None.</p>
<br>
<h3>Parameters</h3>
<dl>
<dt><strong>mutex</strong></dt>
<dd>(Input) Address of the mutex to lock</dd>
</dl>
<br>
<h3>Return Value</h3>
<dl>
<dt><strong>0</strong></dt>
<dd><strong>pthread_mutex_trylock</strong>() was successful.</dd>
<dt><strong>value</strong></dt>
<dd><strong>pthread_mutex_trylock</strong>() was not successful. <em>value</em> is set to indicate the error condition.</dd>
</dl>
<br>
<h3>Error Conditions</h3>
<p>If <strong>pthread_mutex_trylock</strong>() was not successful, the error condition returned usually indicates one of the following errors. Under some conditions, the value returned could indicate an error other than those listed here.</p>
<dl>
<dt><em>[EINVAL]</em></dt>
<dd><p>The value specified for the argument is not correct.</p><br></dd>
<dt><em>[EBUSY]</em></dt>
<dd><p>The mutex is currently locked by another thread.</p>
<p>A thread terminated while holding the mutex, and the mutex is an ownerterm mutex type.</p>
<p>A thread attempted to relock an already held mutex, and the mutex is an errorcheck mutex type.</p></dd>
<dt><em>[ERECURSE]</em></dt>
<dd><p>The recursive mutex cannot be recursively locked again.</p></dd>
</dl>
<br>
<h3>Related Information</h3>
<ul>
<li>The &lt;<strong>pthread.h</strong>> header file. See <a href="rzah4hed.htm">Header files for Pthread functions</a>.<br><br></li>
<li><a href="users_60.htm">pthread_mutex_destroy()</a>--Destroy Mutex<br><br></li>
<li><a href="users_61.htm">pthread_mutex_init()</a>--Initialize Mutex<br><br></li>
<li><a href="users_62.htm">pthread_mutex_lock()</a>--Lock Mutex<br><br></li>
<li><a href="users_63.htm">pthread_mutex_timedlock_np()</a>--Lock Mutex with Time-Out<br><br></li>
<li><a href="users_65.htm">pthread_mutex_unlock()</a>--Unlock Mutex</li>
</ul>
<br>
<h3>Example</h3>
<p>See <a href="../apiref/aboutapis.htm#codedisclaimer">Code disclaimer information</a>
for information pertaining to code examples.</p>
<pre>#include &lt;pthread.h&gt;
#include &lt;stdio.h&gt;
#include &lt;errno.h&gt;
#include &quot;check.h&quot;
/*
This example simulates a number of threads working on a parallel
problem. The threads use pthread_mutex_trylock() so that
they do not spend time blocking on a mutex and instead spend more
of the time making progress towards the final solution. When
trylock fails, the processing is done locally, eventually to
be merged with the final parallel solution.
This example should complete faster than the example for
pthread_mutex_lock() in which threads solve the same parallel
problem but spend more time waiting in resource contention.
*/
#define LOOPCONSTANT 100000
#define THREADS 10
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int i,j,k,l;
void *threadfunc(void *parm)
{
int loop = 0;
int localProcessingCompleted = 0;
int numberOfLocalProcessingBursts = 0;
int processingCompletedThisBurst = 0;
int rc;
for (loop=0; loop&lt;LOOPCONSTANT; ++loop) {
rc = pthread_mutex_trylock(&amp;mutex);
if (rc == EBUSY) {
/* Process continue processing the part of the problem */
/* that we can without the lock. We do not want to waste */
/* time blocking. Instead, we'll count locally. */
++localProcessingCompleted;
++numberOfLocalProcessingBursts;
continue;
}
/* We acquired the lock, so this part of the can be global*/
checkResults(&quot;pthread_mutex_trylock()\n&quot;, rc);
/* Processing completed consist of last local processing */
/* plus the 1 unit of processing this time through */
processingCompletedThisBurst = 1 + localProcessingCompleted;
localProcessingCompleted = 0;
i+=processingCompletedThisBurst; j+=processingCompletedThisBurst;
k+=processingCompletedThisBurst; l+=processingCompletedThisBurst;
rc = pthread_mutex_unlock(&amp;mutex);
checkResults(&quot;pthread_mutex_unlock()\n&quot;, rc);
}
/* If any local processing remains, merge it with the global*/
/* problem so our part of the solution is accounted for */
if (localProcessingCompleted) {
rc = pthread_mutex_lock(&amp;mutex);
checkResults(&quot;final pthread_mutex_lock()\n&quot;, rc);
i+=localProcessingCompleted; j+=localProcessingCompleted;
k+=localProcessingCompleted; l+=localProcessingCompleted;
rc = pthread_mutex_unlock(&amp;mutex);
checkResults(&quot;final pthread_mutex_unlock()\n&quot;, rc);
}
printf(&quot;Thread processed about %d%% of the problem locally\n&quot;,
(numberOfLocalProcessingBursts * 100) / LOOPCONSTANT);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t threadid[THREADS];
int rc=0;
int loop=0;
pthread_attr_t pta;
printf(&quot;Entering testcase\n&quot;);
pthread_attr_init(&amp;pta);
pthread_attr_setdetachstate(&amp;pta, PTHREAD_CREATE_JOINABLE);
printf(&quot;Creating %d threads\n&quot;, THREADS);
for (loop=0; loop&lt;THREADS; ++loop) {
rc = pthread_create(&amp;threadid[loop], &amp;pta, threadfunc, NULL);
checkResults(&quot;pthread_create()\n&quot;, rc);
}
printf(&quot;Wait for results\n&quot;);
for (loop=0; loop&lt;THREADS; ++loop) {
rc = pthread_join(threadid[loop], NULL);
checkResults(&quot;pthread_join()\n&quot;, rc);
}
printf(&quot;Cleanup and show results\n&quot;);
pthread_attr_destroy(&amp;pta);
pthread_mutex_destroy(&amp;mutex);
printf(&quot;\nUsing %d threads and LOOPCONSTANT = %d\n&quot;,
THREADS, LOOPCONSTANT);
printf(&quot;Values are: (should be %d)\n&quot;, THREADS * LOOPCONSTANT);
printf(&quot; ==>%d, %d, %d, %d\n&quot;, i, j, k, l);
printf(&quot;Main completed\n&quot;);
return 0;
}</pre>
<p><strong>Output:</strong></p>
<pre>Entering testcase
Creating 10 threads
Wait for results
Thread processed about 100% of the problem locally
Thread processed about 90% of the problem locally
Thread processed about 88% of the problem locally
Thread processed about 94% of the problem locally
Thread processed about 93% of the problem locally
Thread processed about 96% of the problem locally
Thread processed about 90% of the problem locally
Thread processed about 91% of the problem locally
Thread processed about 81% of the problem locally
Thread processed about 76% of the problem locally
Cleanup and show results
Using 10 threads and LOOPCONSTANT = 100000
Values are: (should be 1000000)
==>1000000, 1000000, 1000000, 1000000
Main completed</pre>
<hr>
API introduced: V4R3
<hr>
<center>
<table cellpadding="2" cellspacing="2">
<tr align="center">
<td valign="middle" align="center"><a href="#Top_Of_Page">Top</a> |
<a href="rzah4mst.htm">Pthread APIs</a> |
<a href="aplist.htm">APIs by category</a></td>
</tr>
</table>
</center>
</body>
</html>