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.