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

326 lines
11 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_create()--Create Thread</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_create()--Create Thread</h2>
<div class="box" style="width: 70%;">
<br>
&nbsp;&nbsp;Syntax:
<pre>
#include &lt;pthread.h&gt;
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
</pre><br>
&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_create</strong>() function creates a thread with the
specified attributes and runs the C function <em>start_routine</em> in the
thread with the single pointer argument specified. The new thread may, but does
not always, begin running before <strong>pthread_create</strong>() returns. If
<strong>pthread_create</strong>() completes successfully, the Pthread handle is
stored in the contents of the location referred to by <em>thread</em>.</p>
<p>If the <em>start_routine</em> returns normally, it is as if there was an
implicit call to <strong>pthread_exit</strong>() using the return value of <em>
start_routine</em> as the status. The function passed as <em>start_routine</em>
should correspond to the following C function prototype:</p>
<pre>
void *threadStartRoutinName(void *);
</pre>
<p>If the thread attributes object represented by <em>attr</em> is modified
later, the newly created thread is not affected. If attr is <strong>
NULL</strong>, the default thread attributes are used.</p>
<p>With the following declarations and initialization,</p>
<pre>
pthread_t t;
void *foo(void *);
pthread_attr_t attr;
pthread_attr_init(&amp;pta);
</pre>
<p>the following two thread creation mechanisms are functionally
equivalent:</p>
<pre>
rc = pthread_create(&amp;t, NULL, foo, NULL);
rc = pthread_create(&amp;t, &amp;attr, foo, NULL);
</pre>
<p>The cancellation state of the new thread is <strong>
PTHREAD_CANCEL_ENABLE</strong>. The cancellation type of the new thread is
<strong>PTHREAD_CANCEL_DEFERRED</strong>.</p>
<p>The signal information maintained in the new thread is as follows:</p>
<ul>
<li>The signal mask is inherited from the creating thread.</li>
<li>The set of signals pending for the new thread is empty.</li>
</ul>
<p>If you attempt to create a thread in a job that is not capable of starting
threads, <strong>pthread_create</strong>() fails with the <strong>
EBUSY</strong> error. If you attempt to create a thread from a location in
which thread creation is not allowed, <strong>pthread_create</strong>() fails
with the <strong>EBUSY</strong> error. See the <strong>
pthread_getpthreadoption_np</strong>() function, option <strong>
PTHREAD_OPTION_THREAD_CAPABLE_NP</strong>, for details about how to determine
whether thread creation is currently allowed in your process.</p>
<p>In the i5/OS implementation, the initial thread is special. Termination of
the initial thread by <strong>pthread_exit</strong>() or any other thread
termination mechanism terminates the entire process.</p>
<p>The i5/OS implementation does not set a hard limit on the number of threads
that can be created. The <strong>PTHREAD_THREADS_MAX</strong> macro is
implemented as a function call, and returns different values depending on the
administrative setting of the maximum number of threads for the process. The
default is NO MAX and has the numeric value of 2147483647 (0x7FFFFFFF).
Realistically, the number of threads is limited by the amount of storage
available to the job.</p>
<p>Currently, thread creation is not allowed after process termination has been
started. For example, after a call to <strong>exit</strong>(), destructors for
C++ static objects, functions registered with <strong>atexit</strong>() or
<strong>CEE4RAGE</strong>() are allowed to run. If these functions attempt to
create a thread, <strong>pthread_create</strong>() fails with the <strong>
EBUSY</strong> error. Similar failures occur if other mechanisms are used to
call <strong>pthread_create</strong>() after process termination has
started.</p>
<br>
<h3>Usage Notes</h3>
<ol>
<li>If you attempt to create a thread in a job that is not capable of starting
threads or for some other reason, thread creation is not allowed, and <strong>
pthread_create</strong>() fails with the <strong>EBUSY</strong> error.</li>
<li>For the best performance during thread creation, you should always use
<strong>pthread_join</strong>() or <strong>pthread_detach</strong>(). This
allows resources to be reclaimed or reused when the thread terminates.</li>
<li>The i5/OS implementation of threads allows the user ID to be changed on a
per-thread basis. If, at the time the application creates the first thread, the
application has not associated a process user identity with the job, the system
uses the identity of the current user to set the process user identity for the
job. The process user identity is used by some operating system support when
operations that require authorization checks are done against a multithreaded
job from outside that job. The application can set the process user identity
using the <a href="QWTSJUID.htm">Set Job User Identify</a> (QWTSJUID) or <a
href="QWTSETJU.htm">QwtSetJuid()</a> Set Job User Identity APIs. See the <a
href="sec.htm">Security</a> APIs for more details.</li>
</ol>
<br>
<h3>Authorities and Locks</h3>
<p>None.</p>
<br>
<h3>Parameters</h3>
<dl>
<dt><strong>thread</strong></dt>
<dd>(Output) Pthread handle to the created thread</dd>
<dt><strong>attr</strong></dt>
<dd>(Input) The thread attributes object containing the attributes to be
associated with the newly created thread. If <strong>NULL,</strong> the default
thread attributes are used.</dd>
<dt><strong>start_routine</strong></dt>
<dd>(Input) The function to be run as the new threads start routine</dd>
<dt><strong>arg</strong></dt>
<dd>(Input) An address for the argument for the threads start routine</dd>
</dl>
<br>
<h3>Return Value</h3>
<dl>
<dt><strong>0</strong></dt>
<dd><strong>pthread_create</strong>() was successful.<br><br></dd>
<dt><strong>value</strong></dt>
<dd><strong>pthread_create</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_create</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></dd>
<dt><em>[EAGAIN]</em></dt>
<dd><p>The system did not have enough resources to create another thread or the maximum
number of threads for this job has been reached.</p></dd>
<dt><em>[EBUSY]</em></dt>
<dd><p>The system cannot allow thread creation in this
process at this time.</p></dd>
</dl>
<br>
<h3>Related Information</h3>
<ul>
<li>The &lt;<strong>pthread.h</strong>&gt; header file. See <a href=
"rzah4hed.htm">Header files for Pthread functions</a>.<br><br></li>
<li><a href="users_18.htm">pthread_exit()</a>--Terminate Calling Thread<br><br></li>
<li><a href="users_39.htm">pthread_cancel()</a>--Cancel Thread<br><br></li>
<li><a href="users_16.htm">pthread_detach()</a>--Detach Thread<br><br></li>
<li><a href="users_25.htm">pthread_join()</a>--Wait for and Detach Thread</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>
#define _MULTI_THREADED
#include &lt;pthread.h&gt;
#include &lt;stdio.h&gt;
#include "check.h"
typedef struct {
int value;
char string[128];
} thread_parm_t;
void *threadfunc(void *parm)
{
thread_parm_t *p = (thread_parm_t *)parm;
printf("%s, parm = %d\n", p-&gt;string, p-&gt;value);
free(p);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t thread;
int rc=0;
pthread_attr_t pta;
thread_parm_t *parm=NULL;
printf("Enter Testcase - %s\n", argv[0]);
printf("Create a thread attributes object\n");
rc = pthread_attr_init(&amp;pta);
checkResults("pthread_attr_init()\n", rc);
/* Create 2 threads using default attributes in different ways */
printf("Create thread using the NULL attributes\n");
/* Set up multiple parameters to pass to the thread */
parm = malloc(sizeof(thread_parm_t));
parm-&gt;value = 5;
strcpy(parm-&gt;string, "Inside secondary thread");
rc = pthread_create(&amp;thread, NULL, threadfunc, (void *)parm);
checkResults("pthread_create(NULL)\n", rc);
printf("Create thread using the default attributes\n");
/* Set up multiple parameters to pass to the thread */
parm = malloc(sizeof(thread_parm_t));
parm-&gt;value = 77;
strcpy(parm-&gt;string, "Inside secondary thread");
rc = pthread_create(&amp;thread, &amp;pta, threadfunc, (void *)parm);
checkResults("pthread_create(&amp;pta)\n", rc);
printf("Destroy thread attributes object\n");
rc = pthread_attr_destroy(&amp;pta);
checkResults("pthread_attr_destroy()\n", rc);
/* sleep() is not a very robust way to wait for the thread */
sleep(5);
printf("Main completed\n");
return 0;
}
</pre>
<p><strong>Output:</strong></p>
<pre>
Enter Testcase - QP0WTEST/TPCRT0
Create a thread attributes object
Create thread using the NULL attributes
Create thread using the default attributes
Destroy thread attributes object
Inside secondary thread, parm = 77
Inside secondary thread, parm = 5
Main completed
</pre>
<br>
<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>