pthread_key_createの使い方

2339 ワード

変換元:http://www.douban.com/note/162329664/
スレッド固有のスレッドストレージ、Thread Specific Dataについてお話しします.スレッドストレージは何に使いますか?どういう意味だ?マルチスレッドプログラムでは、すべてのスレッドがプログラム内の変数を共有していることはよく知られています.グローバル変数があり、すべてのスレッドで使用して値を変更できます.各スレッドが単独で所有したい場合は、スレッドストレージを使用する必要があります.表面的にはグローバル変数のように見え、すべてのスレッドで使用できますが、その値は各スレッドに個別に格納されます.これがスレッドストレージの意味です.スレッドストレージの具体的な使い方について説明します.l pthread_のタイプを作成するkey_tタイプの変数.l pthread_を呼び出すkey_create()を使用して変数を作成します.この関数には2つのパラメータがあり、最初のパラメータは上で宣言したpthread_です.key_t変数、第2のパラメータは、スレッドがスレッドストレージを解放するときに呼び出されるクリーンアップ関数である.この関数ポインタをNULLに設定すると、デフォルトのクリーンアップ関数が呼び出されます.lスレッドに特殊な値を格納する必要がある場合pthread_を呼び出すことができるsetspecific() .この関数には2つのパラメータがあり、1つ目は前に宣言したpthread_です.key_t変数、2番目はvoid*変数で、任意のタイプの値を格納できます.l格納された値を取り出す必要がある場合はpthread_を呼び出すgetspecific() .この関数のパラメータは、前述のpthread_です.key_t変数で、void*タイプの値を返します.次に、前述した関数のプロトタイプを示します:int pthread_setspecific(pthread_key_t key, const void *value); void *pthread_getspecific(pthread_key_t key); int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); スレッドストレージの使用方法の例を次に示します.
 
#include <malloc.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
static pthread_key_t log_key;

void write_log(const char* msg){
	FILE* fp = (FILE*)pthread_getspecific(log_key);
	fprintf(fp, "get a msg:%s
", msg); } void* thread_func(void* args){ static int cnt = 0; char fn[32]; // log , //sprintf(fn, "log/thread.%d.log", (unsigned int)pthread_self()); sprintf(fn, "log/thread.%d.log", ++cnt); FILE* fp = fopen(fn, "w"); if(!fp){ fprintf(stderr, "open file %s error !
", fn); return NULL; } pthread_setspecific(log_key, fp); char msg[64]; sprintf(msg, "I am %s
", fn); write_log(msg); } void close_log_file(void* log_file){ fclose((FILE*)log_file); } int main(){ const int n = 10; pthread_t pids[n]; pthread_key_create(&log_key, close_log_file); for(int i = 0; i < n; i++){ pthread_create(pids+i, NULL, thread_func, NULL); } for(int i = 0; i < n; i++){ pthread_join(pids[i], NULL); } return 0; }