Manpages

名 前

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_functionNULL 以 外 の 値 を 指 定 す る こ と で 、 そ の キ ー に 対 応 す る デ ス ト ラ ク タ 関 数 を 登 録 す る こ と が で き る 。 ス レ ッ ド が 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_deletepthread_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 [AT] 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); }