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.

関連エントリー:

UTF-8 + 文字数カウント

C + システムリソース設定

epoll + 使い方

Automake + 条件コンパイル

gdb + core 解析

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <img localsrc="" alt=""> <pre lang="" line="" escaped="" highlight="">