add directory Ref-docs
This commit is contained in:
260
Ref-docs/POSIX/susv3/functions/pthread_key_create.html
Normal file
260
Ref-docs/POSIX/susv3/functions/pthread_key_create.html
Normal file
@@ -0,0 +1,260 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link type="text/css" rel="stylesheet" href="style.css"><!-- Generated by The Open Group's rhtm tool v1.2.1 -->
|
||||
<!-- Copyright (c) 2001 The Open Group, All Rights Reserved -->
|
||||
<title>pthread_key_create</title>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<script type="text/javascript" language="JavaScript" src="../jscript/codes.js">
|
||||
</script>
|
||||
|
||||
<basefont size="3"> <a name="pthread_key_create"></a> <a name="tag_03_534"></a><!-- pthread_key_create -->
|
||||
<!--header start-->
|
||||
<center><font size="2">The Open Group Base Specifications Issue 6<br>
|
||||
IEEE Std 1003.1-2001<br>
|
||||
Copyright © 2001 The IEEE and The Open Group, All Rights reserved.</font></center>
|
||||
|
||||
<!--header end-->
|
||||
<hr size="2" noshade>
|
||||
<h4><a name="tag_03_534_01"></a>NAME</h4>
|
||||
|
||||
<blockquote>pthread_key_create - thread-specific data key creation</blockquote>
|
||||
|
||||
<h4><a name="tag_03_534_02"></a>SYNOPSIS</h4>
|
||||
|
||||
<blockquote class="synopsis">
|
||||
<div class="box"><code><tt><sup>[<a href="javascript:open_code('THR')">THR</a>]</sup> <img src="../images/opt-start.gif" alt=
|
||||
"[Option Start]" border="0"> #include <<a href="../basedefs/pthread.h.html">pthread.h</a>><br>
|
||||
<br>
|
||||
int pthread_key_create(pthread_key_t *</tt><i>key</i><tt>, void (*</tt><i>destructor</i><tt>)(void*)); <img src=
|
||||
"../images/opt-end.gif" alt="[Option End]" border="0"></tt></code></div>
|
||||
|
||||
<tt><br>
|
||||
</tt></blockquote>
|
||||
|
||||
<h4><a name="tag_03_534_03"></a>DESCRIPTION</h4>
|
||||
|
||||
<blockquote>
|
||||
<p>The <i>pthread_key_create</i>() function shall create a thread-specific data key visible to all threads in the process. Key
|
||||
values provided by <i>pthread_key_create</i>() are opaque objects used to locate thread-specific data. Although the same key value
|
||||
may be used by different threads, the values bound to the key by <a href=
|
||||
"../functions/pthread_setspecific.html"><i>pthread_setspecific</i>()</a> are maintained on a per-thread basis and persist for the
|
||||
life of the calling thread.</p>
|
||||
|
||||
<p>Upon key creation, the value NULL shall be associated with the new key in all active threads. Upon thread creation, the value
|
||||
NULL shall be associated with all defined keys in the new thread.</p>
|
||||
|
||||
<p>An optional destructor function may be associated with each key value. At thread exit, if a key value has a non-NULL destructor
|
||||
pointer, and the thread has a non-NULL value associated with that key, the value of the key is set to NULL, and then the function
|
||||
pointed to is called with the previously associated value as its sole argument. The order of destructor calls is unspecified if
|
||||
more than one destructor exists for a thread when it exits.</p>
|
||||
|
||||
<p>If, after all the destructors have been called for all non-NULL values with associated destructors, there are still some
|
||||
non-NULL values with associated destructors, then the process is repeated. If, after at least {PTHREAD_DESTRUCTOR_ITERATIONS}
|
||||
iterations of destructor calls for outstanding non-NULL values, there are still some non-NULL values with associated destructors,
|
||||
implementations may stop calling destructors, or they may continue calling destructors until no non-NULL values with associated
|
||||
destructors exist, even though this might result in an infinite loop.</p>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="tag_03_534_04"></a>RETURN VALUE</h4>
|
||||
|
||||
<blockquote>
|
||||
<p>If successful, the <i>pthread_key_create</i>() function shall store the newly created key value at *<i>key</i> and shall return
|
||||
zero. Otherwise, an error number shall be returned to indicate the error.</p>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="tag_03_534_05"></a>ERRORS</h4>
|
||||
|
||||
<blockquote>
|
||||
<p>The <i>pthread_key_create</i>() function shall fail if:</p>
|
||||
|
||||
<dl compact>
|
||||
<dt>[EAGAIN]</dt>
|
||||
|
||||
<dd>The system lacked the necessary resources to create another thread-specific data key, or the system-imposed limit on the total
|
||||
number of keys per process {PTHREAD_KEYS_MAX} has been exceeded.</dd>
|
||||
|
||||
<dt>[ENOMEM]</dt>
|
||||
|
||||
<dd>Insufficient memory exists to create the key.</dd>
|
||||
</dl>
|
||||
|
||||
<p>The <i>pthread_key_create</i>() function shall not return an error code of [EINTR].</p>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
<div class="box"><em>The following sections are informative.</em></div>
|
||||
|
||||
<h4><a name="tag_03_534_06"></a>EXAMPLES</h4>
|
||||
|
||||
<blockquote>
|
||||
<p>The following example demonstrates a function that initializes a thread-specific data key when it is first called, and
|
||||
associates a thread-specific object with each calling thread, initializing this object when necessary.</p>
|
||||
|
||||
<pre>
|
||||
<tt>static pthread_key_t key;
|
||||
static pthread_once_t key_once = PTHREAD_ONCE_INIT;
|
||||
<br>
|
||||
static void
|
||||
make_key()
|
||||
{
|
||||
(void) pthread_key_create(&key, NULL);
|
||||
}
|
||||
<br>
|
||||
func()
|
||||
{
|
||||
void *ptr;
|
||||
<br>
|
||||
(void) pthread_once(&key_once, make_key);
|
||||
if ((ptr = pthread_getspecific(key)) == NULL) {
|
||||
ptr = malloc(OBJECT_SIZE);
|
||||
...
|
||||
(void) pthread_setspecific(key, ptr);
|
||||
}
|
||||
...
|
||||
}
|
||||
</tt>
|
||||
</pre>
|
||||
|
||||
<p>Note that the key has to be initialized before <a href="../functions/pthread_getspecific.html"><i>pthread_getspecific</i>()</a>
|
||||
or <a href="../functions/pthread_setspecific.html"><i>pthread_setspecific</i>()</a> can be used. The <i>pthread_key_create</i>()
|
||||
call could either be explicitly made in a module initialization routine, or it can be done implicitly by the first call to a module
|
||||
as in this example. Any attempt to use the key before it is initialized is a programming error, making the code below
|
||||
incorrect.</p>
|
||||
|
||||
<pre>
|
||||
<tt>static pthread_key_t key;
|
||||
<br>
|
||||
func()
|
||||
{
|
||||
void *ptr;
|
||||
<br>
|
||||
/* KEY NOT INITIALIZED!!! THIS WON'T WORK!!! */
|
||||
if ((ptr = pthread_getspecific(key)) == NULL &&
|
||||
pthread_setspecific(key, NULL) != 0) {
|
||||
pthread_key_create(&key, NULL);
|
||||
...
|
||||
}
|
||||
}
|
||||
</tt>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="tag_03_534_07"></a>APPLICATION USAGE</h4>
|
||||
|
||||
<blockquote>
|
||||
<p>None.<br>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="tag_03_534_08"></a>RATIONALE</h4>
|
||||
|
||||
<blockquote>
|
||||
<p></p>
|
||||
|
||||
<h5><a name="tag_03_534_08_01"></a>Destructor Functions</h5>
|
||||
|
||||
<p>Normally, the value bound to a key on behalf of a particular thread is a pointer to storage allocated dynamically on behalf of
|
||||
the calling thread. The destructor functions specified with <i>pthread_key_create</i>() are intended to be used to free this
|
||||
storage when the thread exits. Thread cancelation cleanup handlers cannot be used for this purpose because thread-specific data may
|
||||
persist outside the lexical scope in which the cancelation cleanup handlers operate.</p>
|
||||
|
||||
<p>If the value associated with a key needs to be updated during the lifetime of the thread, it may be necessary to release the
|
||||
storage associated with the old value before the new value is bound. Although the <a href=
|
||||
"../functions/pthread_setspecific.html"><i>pthread_setspecific</i>()</a> function could do this automatically, this feature is not
|
||||
needed often enough to justify the added complexity. Instead, the programmer is responsible for freeing the stale storage:</p>
|
||||
|
||||
<pre>
|
||||
<tt>pthread_getspecific(key, &old);
|
||||
new = allocate();
|
||||
destructor(old);
|
||||
pthread_setspecific(key, new);
|
||||
</tt>
|
||||
</pre>
|
||||
|
||||
<basefont size="2">
|
||||
|
||||
<dl>
|
||||
<dt><b>Note:</b></dt>
|
||||
|
||||
<dd>The above example could leak storage if run with asynchronous cancelation enabled. No such problems occur in the default
|
||||
cancelation state if no cancelation points occur between the get and set.</dd>
|
||||
</dl>
|
||||
|
||||
<basefont size="3">
|
||||
|
||||
<p>There is no notion of a destructor-safe function. If an application does not call <a href=
|
||||
"../functions/pthread_exit.html"><i>pthread_exit</i>()</a> from a signal handler, or if it blocks any signal whose handler may call
|
||||
<a href="../functions/pthread_exit.html"><i>pthread_exit</i>()</a> while calling async-unsafe functions, all functions may be
|
||||
safely called from destructors.</p>
|
||||
|
||||
<h5><a name="tag_03_534_08_02"></a>Non-Idempotent Data Key Creation</h5>
|
||||
|
||||
<p>There were requests to make <i>pthread_key_create</i>() idempotent with respect to a given <i>key</i> address parameter. This
|
||||
would allow applications to call <i>pthread_key_create</i>() multiple times for a given <i>key</i> address and be guaranteed that
|
||||
only one key would be created. Doing so would require the key value to be previously initialized (possibly at compile time) to a
|
||||
known null value and would require that implicit mutual-exclusion be performed based on the address and contents of the <i>key</i>
|
||||
parameter in order to guarantee that exactly one key would be created.</p>
|
||||
|
||||
<p>Unfortunately, the implicit mutual-exclusion would not be limited to only <i>pthread_key_create</i>(). On many implementations,
|
||||
implicit mutual-exclusion would also have to be performed by <a href=
|
||||
"../functions/pthread_getspecific.html"><i>pthread_getspecific</i>()</a> and <a href=
|
||||
"../functions/pthread_setspecific.html"><i>pthread_setspecific</i>()</a> in order to guard against using incompletely stored or
|
||||
not-yet-visible key values. This could significantly increase the cost of important operations, particularly <a href=
|
||||
"../functions/pthread_getspecific.html"><i>pthread_getspecific</i>()</a>.</p>
|
||||
|
||||
<p>Thus, this proposal was rejected. The <i>pthread_key_create</i>() function performs no implicit synchronization. It is the
|
||||
responsibility of the programmer to ensure that it is called exactly once per key before use of the key. Several straightforward
|
||||
mechanisms can already be used to accomplish this, including calling explicit module initialization functions, using mutexes, and
|
||||
using <a href="../functions/pthread_once.html"><i>pthread_once</i>()</a>. This places no significant burden on the programmer,
|
||||
introduces no possibly confusing <i>ad hoc</i> implicit synchronization mechanism, and potentially allows commonly used
|
||||
thread-specific data operations to be more efficient.</p>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="tag_03_534_09"></a>FUTURE DIRECTIONS</h4>
|
||||
|
||||
<blockquote>
|
||||
<p>None.</p>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="tag_03_534_10"></a>SEE ALSO</h4>
|
||||
|
||||
<blockquote>
|
||||
<p><a href="pthread_getspecific.html"><i>pthread_getspecific</i>()</a> , <a href=
|
||||
"pthread_key_delete.html"><i>pthread_key_delete</i>()</a> , the Base Definitions volume of IEEE Std 1003.1-2001, <a href=
|
||||
"../basedefs/pthread.h.html"><i><pthread.h></i></a></p>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="tag_03_534_11"></a>CHANGE HISTORY</h4>
|
||||
|
||||
<blockquote>
|
||||
<p>First released in Issue 5. Included for alignment with the POSIX Threads Extension.</p>
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="tag_03_534_12"></a>Issue 6</h4>
|
||||
|
||||
<blockquote>
|
||||
<p>The <i>pthread_key_create</i>() function is marked as part of the Threads option.</p>
|
||||
|
||||
<p>IEEE PASC Interpretation 1003.1c #8 is applied, updating the DESCRIPTION.</p>
|
||||
</blockquote>
|
||||
|
||||
<div class="box"><em>End of informative text.</em></div>
|
||||
|
||||
<hr>
|
||||
<hr size="2" noshade>
|
||||
<center><font size="2"><!--footer start-->
|
||||
UNIX ® is a registered Trademark of The Open Group.<br>
|
||||
POSIX ® is a registered Trademark of The IEEE.<br>
|
||||
[ <a href="../mindex.html">Main Index</a> | <a href="../basedefs/contents.html">XBD</a> | <a href=
|
||||
"../utilities/contents.html">XCU</a> | <a href="../functions/contents.html">XSH</a> | <a href="../xrat/contents.html">XRAT</a>
|
||||
]</font></center>
|
||||
|
||||
<!--footer end-->
|
||||
<hr size="2" noshade>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user