pthread_key_createのヘルプ・マニュアル
日本語 英語
pthread_key_create --help
man pthread_key_create
PTHREAD_SPECIFIC(3) PTHREAD_SPECIFIC(3)
名前
pthread_key_create, pthread_key_delete, pthread_setspecific,
pthread_getspecific - スレッド固有データの管理
書式
#include
int pthread_key_create(pthread_key_t *key, void (*destr_function) (void
*));
int pthread_key_delete(pthread_key_t key);
int pthread_setspecific(pthread_key_t key, const void *pointer);
void * pthread_getspecific(pthread_key_t key);
説明
プ ログラムではスレッドごとに値の異なるグローバル変数や静的変数がしばし
ば必要となる。複数のスレッドは 1 つのメモリ空間を共有するため、通常の変
数 ではこれを実現することができない。スレッド固有データは、この必要性へ
の POSIX スレッドの答えである。
それぞれのスレッドはスレッド固有データ (thread-specific data) 領域、 略
して TSD 領域というプライベートなメモリブロックを保有している。この領域
は TSD キーをインデックスとして管理される。 TSD 領域では void * 型の 値
を TSD キーに結び付ける。 TSD キーはすべてのスレッドに共通であるが、
TSD キーに結び付けられる値はスレッドごとに異なるようにすることができ る
。
具 体的にいえば、 TSD 領域は void * 型のポインタの配列として、 TSD キー
はこの配列に対する整数値のインデックスとして、 TSD キーに結び付けられる
値は呼び出しスレッドの対応する配列要素として見える。
ス レッドが生成されると、TSD 領域はすべてのキーに対する値が NULL になる
よう初期化される。
pthread_key_create は新しい TSD キーを確保する。キーは key で指し示され
る 領域に格納される。ある時点で確保できるキーの数には制限があり、その最
大値は PTHREAD_KEYS_MAX である。返されたキーに結び付けられる初期値は 、
その時点で実行されているスレッドすべてにおいて NULL である。
引 数 destr_function に NULL 以外の値を指定することで、そのキーに対応す
るデストラクタ関数を登録することができる。スレッドが pthread_exit や キ
ャ ンセルによって終了すると、そのスレッド中でキーに結び付けられた値を引
数として関数 destr_function が呼び出される。値が NULL の場合に は 関 数
destr_function は呼び出されない。スレッド終了時にデストラクタ関数が呼び
出される順序は不定である。
デストラクタ関数が呼び出される前に、現在のスレッドにおいてキーに結び 付
け られる値は NULL になる。しかし、デストラクタ関数は NULL 以外の値をそ
のキーやほかのキーに結び付けるかもしれない。これを処理するため、すべ て
の 非 NULL の値に対するデストラクタ関数をすべて呼び出したあとにデストラ
クタ関数のある非 NULL の値がまだ残っている場合には、デストラクタ関数 の
呼び出し処理は繰り返される。 LinuxThreads の実装では、 PTHREAD_DESTRUC-
TOR_ITERATIONS 回繰り返すと、たとえデストラクタ関数のある非 NULL の値が
残っていても、処理は中止される。LinuxThreads 以外の実装では無限ループに
陥るかもしれない。
pthread_key_delete は TSD キーを解放する。その時点で実行中のスレッド で
キ ーに非 NULL の値が結び付けられているかどうかをチェックしたり、キーに
対応するデストラクタ関数を呼び出したりはしない。
pthread_setspecific は呼び出しスレッドで key に結び付けられる値を、与え
られた pointer に変更する。
pthread_getspecific は呼び出しスレッドでその時点で key に結び付けられて
いる値を返す。
返り値
pthread_key_create および pthread_key_delete 、 pthread_setspecific は
成 功 す る と 0 を、失敗すると非 0 のエラーコードを返す。成功の場合、
pthread_key_create は新しく確保されたキーを引数 key で指し示される領 域
に格納する。
pthread_getspecific は、成功するとキー key に結び付けられた値を、エラー
の場合には NULL を返す。
エラー
pthread_key_create はエラーの場合に次のようなエラーコードを返す:
EAGAIN PTHREAD_KEYS_MAX だけのキーがすでに確保されている。
pthread_key_delete および pthread_setspecific はエラーの場合に次のよ う
なエラーコードを返す:
EINVAL key は有効な、確保された TSD キーではない。
pthread_getspecific は、 key が有効な、確保された TSD キーでない場合に
は NULL を返す。
著者
Xavier Leroy
関連項目
pthread_create(3), pthread_exit(3), pthread_testcancel(3).
例
次のコードでは、100 バイトのスレッド固有の配列を確保し、スレッドの終 了
とともに自動で解放する:
/* スレッド固有バッファのキー */
static pthread_key_t buffer_key;
/* 1 回限りのキーの初期化 */
static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
/* スレッド固有のバッファを確保する */
void buffer_alloc(void)
{
pthread_once(&buffer_key_once, buffer_key_alloc);
pthread_setspecific(buffer_key, malloc(100));
}
/* スレッド固有のバッファを返す */
char * get_buffer(void)
{
return (char *) pthread_getspecific(buffer_key);
}
/* キーを確保する */
static void buffer_key_alloc()
{
pthread_key_create(&buffer_key, buffer_destroy);
}
/* スレッド固有のバッファを解放する */
static void buffer_destroy(void * buf)
{
free(buf);
}
LinuxThreads PTHREAD_SPECIFIC(3)
PTHREAD_KEY_CREATE(3P) POSIX Programmer’s Manual PTHREAD_KEY_CREATE(3P)
PROLOG
This manual page is part of the POSIX Programmer’s Manual. The Linux
implementation of this interface may differ (consult the corresponding
Linux manual page for details of Linux behavior), or the interface may
not be implemented on Linux.
NAME
pthread_key_create - thread-specific data key creation
SYNOPSIS
#include
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
DESCRIPTION
The pthread_key_create() function shall create a thread-specific data
key visible to all threads in the process. Key values provided by
pthread_key_create() 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 pthread_setspecific() are maintained on a
per-thread basis and persist for the life of the calling thread.
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.
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.
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 destruc-
tors, or they may continue calling destructors until no non-NULL values
with associated destructors exist, even though this might result in an
infinite loop.
RETURN VALUE
If successful, the pthread_key_create() function shall store the newly
created key value at *key and shall return zero. Otherwise, an error
number shall be returned to indicate the error.
ERRORS
The pthread_key_create() function shall fail if:
EAGAIN 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.
ENOMEM Insufficient memory exists to create the key.
The pthread_key_create() function shall not return an error code of
[EINTR].
The following sections are informative.
EXAMPLES
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.
static pthread_key_t key;
static pthread_once_t key_once = PTHREAD_ONCE_INIT;
static void
make_key()
{
(void) pthread_key_create(&key, NULL);
}
func()
{
void *ptr;
(void) pthread_once(&key_once, make_key);
if ((ptr = pthread_getspecific(key)) == NULL) {
ptr = malloc(OBJECT_SIZE);
...
(void) pthread_setspecific(key, ptr);
}
...
}
Note that the key has to be initialized before pthread_getspecific() or
pthread_setspecific() can be used. The pthread_key_create() 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.
static pthread_key_t key;
func()
{
void *ptr;
/* KEY NOT INITIALIZED!!! THIS WON’T WORK!!! */
if ((ptr = pthread_getspecific(key)) == NULL &&
pthread_setspecific(key, NULL) != 0) {
pthread_key_create(&key, NULL);
...
}
}
APPLICATION USAGE
None.
RATIONALE
Destructor Functions
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 pthread_key_create()
are intended to be used to free this storage when the thread exits.
Thread cancellation cleanup handlers cannot be used for this purpose
because thread-specific data may persist outside the lexical scope in
which the cancellation cleanup handlers operate.
If the value associated with a key needs to be updated during the life-
time of the thread, it may be necessary to release the storage associ-
ated with the old value before the new value is bound. Although the
pthread_setspecific() function could do this automatically, this fea-
ture is not needed often enough to justify the added complexity.
Instead, the programmer is responsible for freeing the stale storage:
pthread_getspecific(key, &old);
new = allocate();
destructor(old);
pthread_setspecific(key, new);
Note: The above example could leak storage if run with asynchronous
cancellation enabled. No such problems occur in the default can-
cellation state if no cancellation points occur between the get
and set.
There is no notion of a destructor-safe function. If an application
does not call pthread_exit() from a signal handler, or if it blocks any
signal whose handler may call pthread_exit() while calling async-unsafe
functions, all functions may be safely called from destructors.
Non-Idempotent Data Key Creation
There were requests to make pthread_key_create() idempotent with
respect to a given key address parameter. This would allow applications
to call pthread_key_create() multiple times for a given key 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 key
parameter in order to guarantee that exactly one key would be created.
Unfortunately, the implicit mutual-exclusion would not be limited to
only pthread_key_create(). On many implementations, implicit mutual-
exclusion would also have to be performed by pthread_getspecific() and
pthread_setspecific() in order to guard against using incompletely
stored or not-yet-visible key values. This could significantly increase
the cost of important operations, particularly pthread_getspecific().
Thus, this proposal was rejected. The pthread_key_create() 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 func-
tions, using mutexes, and using pthread_once(). This places no signifi-
cant burden on the programmer, introduces no possibly confusing ad hoc
implicit synchronization mechanism, and potentially allows commonly
used thread-specific data operations to be more efficient.
FUTURE DIRECTIONS
None.
SEE ALSO
pthread_getspecific(), pthread_key_delete(), the Base Definitions vol-
ume of IEEE Std 1003.1-2001,
COPYRIGHT
Portions of this text are reprinted and reproduced in electronic form
from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology
-- Portable Operating System Interface (POSIX), The Open Group Base
Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of
Electrical and Electronics Engineers, Inc and The Open Group. In the
event of any discrepancy between this version and the original IEEE and
The Open Group Standard, the original IEEE and The Open Group Standard
is the referee document. The original Standard can be obtained online
at http://www.opengroup.org/unix/online.html .
IEEE/The Open Group 2003 PTHREAD_KEY_CREATE(3P)