pthread_key + 使い方

pthread_key 周辺の使い方を勉強。
スレッドごとにメモリ領域を確保する仕組み。

#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <pthread.h>  
  
static pthread_key_t g_key;  
  
// スレッド単位で保持するデータ  
struct MyData{  
    int count;  
    char data;  
};  
  
static void* thread_call( void *arg )  
{  
    pthread_t self_id = pthread_self();  
    printf( "self_id:%u\n", self_id );  
      
    // データがすでに存在するか調査  
    struct MyData *p;  
    if( pthread_getspecific( g_key ) ){  
        printf( "self_id:%u Already exists.", self_id );  
        return NULL;  
    }  
  
    // データ作成  
    if( !(p = (struct MyData *)calloc( 1, sizeof(*p) )) ){  
        perror( "calloc()" );  
        return NULL;  
    }  
    pthread_setspecific( g_key, p );  
    p->count = 0;  
    p->data = 'A';  
  
    // 本当にスレッド単位で保持されているかテスト  
    int i;  
    for( i = 0; i < 26; ++i ){  
        p = (struct MyData *)(pthread_getspecific( g_key ));  
        printf( "self_id:%u id:%u data:%c\n", self_id, p->count++, p->data++ );  
        usleep(1000);  
    }  
    p = (struct MyData *)(pthread_getspecific( g_key ));  
    if( p->count == 26 ){  
        printf( "self_id:%u success.\n", self_id );  
    }  
    else{  
        printf( "self_id:%u error!!\n", self_id );  
    }  
  
    // 終了  
    free(p);  
    pthread_setspecific( g_key, 0 );  
}  
  
int main()  
{  
    // pthread key を初期化  
    if( pthread_key_create( &g_key, NULL ) ){  
        perror( "pthread_key_create()" );  
        return 0;  
    }  
  
    // スレッドを複数作成。  
    const int TNUM = 3;  
    pthread_t tid[TNUM];  
    int i;  
    for( i = 0; i < TNUM; ++i ){  
        if( pthread_create( &tid[i], NULL, thread_call, NULL ) ){  
            perror( "pthread_create()" );  
            continue;  
        }  
        printf( "Created a thread. id:%u\n", tid[i] );  
    }  
  
    // 全スレッドが終了するのを待機。  
    for( i = 0; i < TNUM; ++i ){  
        pthread_join( tid[i], NULL );  
    }  
      
    // pthread key を削除  
    pthread_key_delete( g_key );      
    return 0;  
}  

実行

$ gcc main.c -lpthread  
$ ./a.out  
Created a thread. id:663552  
Created a thread. id:2625536  
Created a thread. id:3162112  
self_id:663552  
self_id:2625536  
self_id:3162112  
self_id:663552 id:0 data:A  
self_id:2625536 id:0 data:A  
self_id:3162112 id:0 data:A  
self_id:663552 id:1 data:B  
self_id:2625536 id:1 data:B  
...  
self_id:2625536 id:25 data:Z  
self_id:663552 success.  
self_id:3162112 id:25 data:Z  
self_id:2625536 success.  
self_id:3162112 success.