TSDのいくつかの関数、pthread_key_create pthread_getspecific
2942 ワード
マルチスレッドプログラムでは、複数の関数間のデータ共有をグローバル変数で実現することがよくあります.データ空間は共有されるため、グローバル変数もすべてのプロセスに共有されます.しかし、アプリケーション設計では、スレッドにのみ有効なスレッドプライベートのグローバル変数を提供する必要がある場合がありますが、複数の関数にまたがってアクセスできます.
たとえば、プログラムでは、スレッドごとにチェーンテーブルを維持する必要があり、同じ関数を使用してこのチェーンテーブルを操作する場合、最も簡単な方法は、同じ名前で異なる変数アドレスのスレッド関連データ構造を使用することです.このようなデータ構造は、Posixスレッドライブラリによって維持され、スレッドプライベートデータ(Thread-specific Data、またはTSD)となる.
ここでは主にスレッドのプライベートデータに関する4つの関数をテストします:pthread_key_create(); pthread_key_delete(); pthread_getspecific(); pthread_setspecific(); プログラムコード:
実行と出力:
出力で表示、pthread_getspecific()はkeyに関連付けられたデータのポインタを返します.なお、この返されるポインタを利用する場合、まずvoidタイプであり、関連するデータアドレスを指すが、指すデータタイプが分からないため、具体的な使用時には強制タイプ変換を行う.
次に,2つのスレッドは自分のプライベートデータ操作に互いに影響を及ぼさない.つまり、keyは同名でグローバルですが、アクセスするメモリ領域は同じではありません.keyはデータ管理者のようなもので、スレッドのプライベートデータは彼のところに登録して、あなたのデータの存在を知らせます.
(PS:上記の内容もスレッドとプロセスの違い、つまりこのTSD)
たとえば、プログラムでは、スレッドごとにチェーンテーブルを維持する必要があり、同じ関数を使用してこのチェーンテーブルを操作する場合、最も簡単な方法は、同じ名前で異なる変数アドレスのスレッド関連データ構造を使用することです.このようなデータ構造は、Posixスレッドライブラリによって維持され、スレッドプライベートデータ(Thread-specific Data、またはTSD)となる.
ここでは主にスレッドのプライベートデータに関する4つの関数をテストします:pthread_key_create(); pthread_key_delete(); pthread_getspecific(); pthread_setspecific(); プログラムコード:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_key_t key;
struct test_struct {
int i;
float k;
};
void *child1 (void*arg)
{
struct test_struct struct_data;
struct_data.i=10;
struct_data.k=3.1415;
pthread_setspecific (key,&struct_data);
printf (" struct_data 0x%p
",&(struct_data));
printf ("child1 pthread_getspecific(key) :0x%p
", (structtest_struct*)pthread_getspecific(key));
printf (" pthread_getspecific(key) child1 key :
struct_data.i:%d
struct_data.k: %f
", ((structtest_struct*)pthread_getspecific (key))->i, ((structtest_struct *)pthread_getspecific(key))->k);
printf ("------------------------------------------------------
");
}
void *child2 (void*arg)
{
int temp = 20;
sleep (2);
printf ("child2 temp 0x%p
", &temp);
pthread_setspecific (key,&temp);
printf ("child2 pthread_getspecific(key) :0x%p
", (int*)pthread_getspecific(key));
printf (" pthread_getspecific(key) child2 key temp :%d
",*((int*)pthread_getspecific(key)));
}
int main (void)
{
pthread_t tid1,tid2;
pthread_key_create (&key,NULL);
pthread_create (&tid1,NULL, (void*)child1,NULL);
pthread_create (&tid2,NULL, (void*)child2,NULL);
pthread_join (tid1,NULL);
pthread_join (tid2,NULL);
pthread_key_delete (key);
return (0);
}
実行と出力:
./pthread_key
struct_data 0x0xb7699388
child1 pthread_getspecific(key) :0x0xb7699388
pthread_getspecific(key) child1 key :
struct_data.i:10
struct_data.k: 3.141500
------------------------------------------------------
child2 temp 0x0xb6e9838c
child2 pthread_getspecific(key) :0x0xb6e9838c
出力で表示、pthread_getspecific()はkeyに関連付けられたデータのポインタを返します.なお、この返されるポインタを利用する場合、まずvoidタイプであり、関連するデータアドレスを指すが、指すデータタイプが分からないため、具体的な使用時には強制タイプ変換を行う.
次に,2つのスレッドは自分のプライベートデータ操作に互いに影響を及ぼさない.つまり、keyは同名でグローバルですが、アクセスするメモリ領域は同じではありません.keyはデータ管理者のようなもので、スレッドのプライベートデータは彼のところに登録して、あなたのデータの存在を知らせます.
(PS:上記の内容もスレッドとプロセスの違い、つまりこのTSD)