プライベートデータ--TSD
2721 ワード
マルチスレッド環境では、プロセス内のすべてのスレッドがプロセスのデータ空間を共有するため、グローバル変数はすべてのスレッドに共有されます.プログラム設計では、スレッド自体のグローバル変数を保存する必要がある場合があります.この特殊な変数は、あるスレッド内部でのみ有効です.一般的な変数errnoのように、標準のエラーコードを返します.errnoは局所変数ではなく、ほとんどの関数がアクセスできるはずです.しかし、グローバル変数ではありません.そうしないと、1つのスレッドに出力されるエラー情報は、スレッドのプライベートデータ(TSD)を作成することで解決できます.
スレッドプライベートデータは、1つのキーが複数の数値に対応する1つのキー多値技術と呼ばれる技術を採用している.データにアクセスするときはキー値でアクセスしますが、1つの変数にアクセスするようですが、実は異なるデータにアクセスしています.スレッドプライベートデータを使用する場合は、まず各スレッドデータに関連付けられたキーを作成します.各スレッドの内部では、この共通のキーを使用してスレッドデータを指すが、異なるスレッドでは、このキーが表すデータは異なる.操作スレッドのプライベートデータの関数は主に4つあります:pthread_key_create(キーを作成)、pthread_setspecific(キーにスレッドプライベートデータを設定)、pthread_getspecific(1つのキーからスレッドのプライベートデータを読み出す)、pthread_key_delete(キーを削除します).これらの関数は次のように宣言されます.
pthread_key_create:LinuxのTSDプールから、後でアクセスするためにkeyに値を割り当てます.最初のパラメータはキー値を指すポインタで、2番目のパラメータは関数ポインタで、ポインタが空でない場合は、スレッド終了時にkeyに関連付けられたデータをパラメータとしてdestr_を呼び出します.function()は、割り当てられたバッファを解放します.
keyが作成されると、すべてのスレッドがアクセスできますが、各スレッドは自分のニーズに応じてkeyに異なる値を入力できます.これは、同じ名前で異なる値を提供するグローバル変数、1つのキーで複数の値に相当します.ワンタッチ多値は、TSDプールという重要なデータ構造配列に依存します.
TSDを作成することは、構造配列のいずれかを「in_use」に設定し、*keyにインデックスを返し、destructor関数をdestr_に設定することに相当します.function.
pthread_setspecific:pointerの値(コンテンツではない)をkeyに関連付けます.pthread_でsetspecificがキーに新しいスレッドデータを指定する場合、スレッドはまず既存のスレッドデータを解放して空間を回収する必要があります. pthread_getspecific:keyに関連付けられたデータをこの関数で取得します.
pthread_key_delete:この関数はキーを削除するために使用され、削除するとキーに使用されるメモリが解放されます.なお、キーが占有するメモリは解放され、キーに関連付けられたスレッドデータが占有するメモリは解放されない.したがって、スレッドデータの解放は、キーの解放前に完了する必要があります.
スレッドプライベートデータは、1つのキーが複数の数値に対応する1つのキー多値技術と呼ばれる技術を採用している.データにアクセスするときはキー値でアクセスしますが、1つの変数にアクセスするようですが、実は異なるデータにアクセスしています.スレッドプライベートデータを使用する場合は、まず各スレッドデータに関連付けられたキーを作成します.各スレッドの内部では、この共通のキーを使用してスレッドデータを指すが、異なるスレッドでは、このキーが表すデータは異なる.操作スレッドのプライベートデータの関数は主に4つあります:pthread_key_create(キーを作成)、pthread_setspecific(キーにスレッドプライベートデータを設定)、pthread_getspecific(1つのキーからスレッドのプライベートデータを読み出す)、pthread_key_delete(キーを削除します).これらの関数は次のように宣言されます.
#include
int pthread_key_create(pthread_key_t *key, void (*destr_function)(void *));
int pthread_setspecific(pthread_key_t key, const void *pointer);
void* pthread_getspecific(pthread_ket_t key);
int pthread_key_delete(pthread_key_t key);
pthread_key_create:LinuxのTSDプールから、後でアクセスするためにkeyに値を割り当てます.最初のパラメータはキー値を指すポインタで、2番目のパラメータは関数ポインタで、ポインタが空でない場合は、スレッド終了時にkeyに関連付けられたデータをパラメータとしてdestr_を呼び出します.function()は、割り当てられたバッファを解放します.
keyが作成されると、すべてのスレッドがアクセスできますが、各スレッドは自分のニーズに応じてkeyに異なる値を入力できます.これは、同じ名前で異なる値を提供するグローバル変数、1つのキーで複数の値に相当します.ワンタッチ多値は、TSDプールという重要なデータ構造配列に依存します.
static struct pthread_key_struct pthread_keys[PTHREAD_KEY_MAX] = { {0, NULL} };
TSDを作成することは、構造配列のいずれかを「in_use」に設定し、*keyにインデックスを返し、destructor関数をdestr_に設定することに相当します.function.
pthread_setspecific:pointerの値(コンテンツではない)をkeyに関連付けます.pthread_でsetspecificがキーに新しいスレッドデータを指定する場合、スレッドはまず既存のスレッドデータを解放して空間を回収する必要があります. pthread_getspecific:keyに関連付けられたデータをこの関数で取得します.
pthread_key_delete:この関数はキーを削除するために使用され、削除するとキーに使用されるメモリが解放されます.なお、キーが占有するメモリは解放され、キーに関連付けられたスレッドデータが占有するメモリは解放されない.したがって、スレッドデータの解放は、キーの解放前に完了する必要があります.
#include
#include
pthread_key_t key;
void* pthr11(void *arg)
{
int val = 11;
pthread_setspecific(key, (void*)val);
printf("pthread:%u, returns:%d
", pthread_self(), pthread_getspecific(key));
}
void* pthr22(void *arg)
{
int val = 22;
pthread_setspecific(key, (void*)val);
printf("pthread:%u, returns:%d
", pthread_self(), pthread_getspecific(key));
}
int main(void)
{
pthread_t pthr1;
pthread_key_create(&key, NULL);
pthread_create(&pthr1, NULL, pthr11, NULL);
pthread_t pthr2;
pthread_create(&pthr2, NULL, pthr22, NULL);
sleep(5);
pthread_key_delete(key);
int retval;
pthread_exit(&retval);
return 0;
}