pthread_getspecific() - キーに対応するスレッド固有の値の取得

標準

標準/拡張機能 C/C++ 依存項目

POSIX.4a
Single UNIX Specification、バージョン 3

両方

POSIX(ON)

形式

#define _OPEN_THREADS
#include <pthread.h>

int pthread_getspecific(pthread_key_t key, void **value);
SUSV3:
#define _UNIX03_THREADS 
#include <pthread.h>
void *pthread_getspecific(pthread_key_t key);

機能説明

現行スレッドで指定された key と関連したスレッド固有のデータを 戻します。スレッド固有のデータが key に設定されていない場合には、NULL 値が value に戻されます。

多くのマルチスレッド・アプリケーションでは、各スレッドが固有の値をとるストレージをスレッド間で共用することが必要です。スレッド固有のデータ・キーはスレッドによって作成された ID で、それに対してプロセス内の各スレッドは固有のキー value を 設定できます。

pthread_key_t は、システムがキー ID を入れるストレージです。キーを作成する場合、スレッドは pthread_key_create() を使用します。 この関数は、キー ID を pthread_key_t 型のストレージ域に戻します。 この時点で、アプリケーションの各スレッドは、そのキーを使用でき、 pthread_setspecific() を使用してその固有値を設定できます。 スレッドは、pthread_getspecific() を使用して固有の値を取得します。

戻り値

正常に実行されなかった場合、pthread_getspecific() は errno を次のいずれかの 値に設定します。
エラー・コード
説明
EINVAL
key 用の値は無効です。
注: SUSV3 では、キーが無効の場合、pthread_getspecific() は NULL を戻しますが、 errno 値を設定または戻すことはしません。

CELEBP31
⁄* CELEBP31 *⁄
#ifndef _OPEN_THREADS
#define _OPEN_THREADS
#endif

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>

#define threads 3
#define BUFFSZ  48
pthread_key_t   key;

void            *threadfunc(void *parm)
{
 int        status;
 void      *value;
 int        threadnum;
 int       *tnum;
 void      *getvalue;
 char       Buffer[BUFFSZ];

 tnum = parm;
 threadnum = *tnum;

 printf("Thread %d executing¥n", threadnum);

 if (!(value = malloc(sizeof(Buffer))))
     printf("Thread %d could not allocate storage, errno = %d¥n",
                                                  threadnum, errno);
 status = pthread_setspecific(key, (void *) value);
 if ( status <  0) {
    printf("pthread_setspecific failed, thread %d, errno %d",
                                                  threadnum, errno);
    pthread_exit((void *)12);
 }
 printf("Thread %d setspecific value: %d¥n", threadnum, value);

 getvalue = 0;
 status = pthread_getspecific(key, &getvalue);
 if ( status <  0) {
    printf("pthread_getspecific failed, thread %d, errno %d",
                                                  threadnum, errno);
    pthread_exit((void *)13);
 }

 if (getvalue != value)
 {
   printf("getvalue not valid, getvalue=%d", (int)getvalue);
   pthread_exit((void *)68);
 }

 pthread_exit((void *)0);
}

void  destr_fn(void *parm)
{

   printf("Destructor function invoked¥n");
   free(parm);
}

main() {
 int          getvalue;
 int          status;
 int          i;
 int          threadparm[threads];
 pthread_t    threadid[threads];
 int          thread_stat[threads];


 if ((status = pthread_key_create(&key, destr_fn )) < 0) {
    printf("pthread_key_create failed, errno=%d", errno);
    exit(1);
 }

 ⁄* create 3 threads, pass each its number *⁄
 for (i=0; i<threads; i++) {
    threadparm[i] = i+1;
    status = pthread_create( &threadid[i],
                             NULL,
                             threadfunc,
                             (void *)&threadparm[i]);
    if ( status <  0) {
       printf("pthread_create failed, errno=%d", errno);
       exit(2);
    }
  }

 for ( i=0; i<threads; i++) {
    status = pthread_join( threadid[i], (void *)&thread_stat[i]);
    if ( status <  0) {
       printf("pthread_join failed, thread %d, errno=%d¥n", i+1, errno);
    }

    if (thread_stat[i] != 0)   {
        printf("bad thread status, thread %d, status=%d¥n", i+1,
                                                   thread_stat[i]);
      }
  }

 exit(0);
}

CELEBP70

⁄* CELEBP70 *⁄
⁄* Example using SUSv3 pthread_getspecific() interface *⁄ 

#define _UNIX03_THREADS  1

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>

#define threads 3
#define BUFFSZ  48
pthread_key_t   key;

void            *threadfunc(void *parm)
{
 int        status;
 void      *value;
 int        threadnum;
 int       *tnum;
 void      *getvalue;
 char       Buffer[BUFFSZ];

 tnum = parm;
 threadnum = *tnum;

 printf("Thread %d executing¥n", threadnum);

 if (!(value = malloc(sizeof(Buffer))))
     printf("Thread %d could not allocate storage, errno = %d¥n",
                                                  threadnum, errno);
 status = pthread_setspecific(key, (void *) value);
 if ( status <  0) {
    printf("pthread_setspecific failed, thread %d, errno %d",
                                                  threadnum, errno);
    pthread_exit((void *)12);
 }
 printf("Thread %d setspecific value: %d¥n", threadnum, value);

 getvalue = 0;
 getvalue = pthread_getspecific(key);
 if ( getvalue ==  0) {
    printf("pthread_getspecific failed, thread %d", threadnum);
    printf("   rc= %d, errno %d, ejr %08x¥n",(int)getvalue, errno, __errno2());
    pthread_exit((void *)13);
 } else {
   printf("Success!¥n");
   printf("Returned value: %d matches set value: %d¥n", getvalue, value);
 }

 if (getvalue != value)
 {
   printf("getvalue not valid, getvalue=%d", (int)getvalue);
   pthread_exit((void *)68);
 }

 pthread_exit((void *)0);
}

void  destr_fn(void *parm)
{

   printf("Destructor function invoked¥n");
   free(parm);
}

int main(void)
{
  int          status;
  int          i;
  int          threadparm[threads];
  pthread_t    threadid[threads];
  int          thread_stat[threads];


  if ((status = pthread_key_create(&key, destr_fn )) < 0) {
     printf("pthread_key_create failed, errno=%d", errno);
     exit(1);
  }

  ⁄* create 3 threads, pass each its number *⁄
  for (i=0; i<threads; i++) {
      threadparm[i] = i+1;
     status = pthread_create( &threadid[i],
                               NULL,
                              threadfunc,
                              (void *)&threadparm[i]);
     if ( status <  0) {
        printf("pthread_create failed, errno=%d", errno);
        exit(2);
     }
  }

  for ( i=0; i<threads; i++) {
      status = pthread_join( threadid[i], (void *)&thread_stat[i]);
      if ( status <  0) {
         printf("pthread_join failed, thread %d, errno=%d¥n", i+1, errno);
      }

      if (thread_stat[i] != 0)   {
         printf("bad thread status, thread %d, status=%d¥n", i+1,
                                                   thread_stat[i]);
      }
  }

  exit(0);
}

関連情報