プライベートデータ--TSD


マルチスレッド環境では、プロセス内のすべてのスレッドがプロセスのデータ空間を共有するため、グローバル変数はすべてのスレッドに共有されます.プログラム設計では、スレッド自体のグローバル変数を保存する必要がある場合があります.この特殊な変数は、あるスレッド内部でのみ有効です.一般的な変数errnoのように、標準のエラーコードを返します.errnoは局所変数ではなく、ほとんどの関数がアクセスできるはずです.しかし、グローバル変数ではありません.そうしないと、1つのスレッドに出力されるエラー情報は、スレッドのプライベートデータ(TSD)を作成することで解決できます.
       スレッドプライベートデータは、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; }