Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all
名前
pthread_key_create, pthread_key_delete, pthread_setspecific, pthread_getspecific - スレッ ド固有データの管理
書式
#include <pthread.h> 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_DESTRUCTOR_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 <Xavier.Leroy@inria.fr>
関連項目
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)