您的位置:首页 > 编程语言

【多线程编程】线程私有数据(TSD)

2017-10-14 16:11 369 查看
Thread Specific Data(TSD)

线程私有数据,有什么用呢?在多线程中,经常要用全局变量来实现多个函数间的数据共享。由于数据空间是共享的,因此全局变量也为所有进程共有。但有时应用程序设计中必要提供线程私有的全局变量,这个变量被各个线程私有,但却可以跨过多个函数访问。

书上是这样说的:



int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
该函数有两个参数,第一个参数是 pthread_key_t 变量指针,第二个参数是一个析构函数指针,在线程释放该线程存储时被调用,该函数指针可以设成 NULL,这样系统将调用默认的析构函数。析构函数正常返回0,其他任何返回值都表示出现了错误。

另外还有:

int pthread_setspecific(pthread_key_t key, const void *value);
当线程中需要存储特殊值的时候,可以调用 pthread_setspcific() 。该函数有两个参数,第一个为前面声明的pthread_key_t变量,第二个为void*变量,这样你可以存储任何类型的值。

void *pthread_getspecific(pthread_key_t key);
如果需要取出所存储的值,调用pthread_getspecific()。该函数的参数为前面提到的pthread_key_t变量,该函数返回void *类型的值。

下面用例子来说明:

#include <stdio.h>
#include <pthread.h>

pthread_key_t key;
pthread_once_t once = PTHREAD_ONCE_INIT; // pthread_once 保证 create_key 只被执行一次

void create_key()
{
printf("init pthread_key\n");
if (pthread_key_create(&key, NULL))
{
printf("pthread_key_create failed");
}
}

void display()
{
printf("I'm %u\n", *(int *)pthread_getspecific(key));
}

void * worker(void *arg)
{
pthread_once(&once, create_key);
pthread_t pid = pthread_self();
pthread_setspecific(key, &pid);
printf("%x %x\n", &pid, (int *)pthread_getspecific(key));
display();
}

int main()
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, worker, NULL);
pthread_create(&tid2, NULL, worker, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_key_delete(key);

return 0;
}

输出如下:
init pthread_key
9c6e5f40 9c6e5f40
I'm 2624481024
9bee4f40 9bee4f40
I'm 2616088320

pthread_getspecific() 返回的是与key 相关联数据的指针。需要注意的是,在利用这个返回的指针时,它首先是 void 类型的,它虽然指向关联的数据地址处,但并不知道指向的数据类型,所以在具体使用时,要对其进行强制类型转换。其次,两个线程对自己的私有数据操作是互相不影响的。也就是说,虽然 key 是同名且全局,但访问的内存空间并不是相同的一个。此外,各线程可以用 key 绑定不同类型的数据(我这里都绑定的 int )。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: