私有数据--TSD

原创 2018年04月15日 14:11:28

       在多线程环境下,进程内的所有线程共享进程的数据空间,因此全局变量为所有线程共有。在程序设计中有时需要保存线程自己的全局变量,这种特殊的变量仅在某个线程内部有效。如常见的变量errno,它返回标准的出错代码。errno不应该是一个局部变量,几乎每个函数都应该可以访问它;但它又不能是一个全局变量,否则在一个线程里输出的很可能是另一个线程的出错信息,这个问题可以通过创建线程的私有数据(TSD)来解决。

       线程私有数据采用了一种被称为一键多值技术,即一个键对应多个数值。访问数据时都是通过键值来访问,好像是对一个变量进行访问,其实是在访问不同的数据。使用线程私有数据时,首先要为每个线程数据创建一个相关联的键。在各个线程内部,都使用这个公用的键来指代线程数据,但是在不同的线程中,这个键代表的数据是不同的。操作线程私有数据的函数主要有4个:pthread_key_create(创建一个键), pthread_setspecific(为一个键设置线程私有数据),pthread_getspecific(从一个键读取线程私有数据),pthread_key_delete(删除一个键)。这几个函数声明如下:

#include <pthread>
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供以后访问使用,它的第一个参数为指向键值的指针,第二个参数为一个函数指针,如果指针不为空,则在线程退出时将以key所关联的数据为参数调用destr_function(),释放分配的缓冲区。
key一旦被创建,所有线程都可访问它,但各线程可根据自己的需求往key中填入不同的值,这就相当于提供了一个同名而不同值的全局变量,一键多值。一键多值靠的是一个关键数据结构数组,即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 <stdio.h>
#include <pthread.h>

pthread_key_t key;

void* pthr11(void *arg)
{
    int val = 11;
    pthread_setspecific(key, (void*)val);
    printf("pthread:%u, returns:%d\n", pthread_self(), pthread_getspecific(key));
    
}

void* pthr22(void *arg)
{
    int val = 22;
    pthread_setspecific(key, (void*)val);
    printf("pthread:%u, returns:%d\n", 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;
}


GIS数据的坐标系

-
  • 1970年01月01日 08:00

线程特定数据TSD及其实现原理

引言: 单线程C程序有两类基本数据:局部数据和全局数据。对于多线程C程序,添加了第三类数据:线程特定数据 那么为什么要引入线程特定数据呢?试想如果你的一个线程里面嵌套调用了很多函数,而你又想在这些函数...
  • mengxingyuanlove
  • mengxingyuanlove
  • 2016-03-04 14:44:51
  • 1198

线程的私有数据(TSD)

我们知道 一个进程内的所有线程继承其数据与环境变量,共享数据空间,但是有时候我们需要有的线程拥有独属于其自己的数据变量,让其只在某个线程内有效,比如最常见的errno,每个线程出错的原因大不相同。 这...
  • weixin_36888577
  • weixin_36888577
  • 2017-08-05 09:40:01
  • 127

线程私有数据TSD

在单线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据。在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有。但有时应用程序设计中有必要提供线程私有的全局变量,仅在某个线程...
  • liuxuejiang158
  • liuxuejiang158
  • 2013-11-03 10:50:21
  • 1710

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

Thread Specific Data(TSD) 线程存储,有什么用呢?现在有一全局变量,所有线程都可以使用它,改变它的值。而如果每个线程希望能单独拥有它,那么就需要使用线程存储了。表面上看起来这是...
  • woxiaohahaa
  • woxiaohahaa
  • 2017-10-14 16:11:50
  • 252

linux 多线程编程 Thread Specific Data (TSD)

在单线程程序中,我们经常使用 “全局变量” 以实现多个函数间共享数据,在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共享。但有时应用程序设计中有必要提供线程私有的全局变量,仅在某个线...
  • kennyrose
  • kennyrose
  • 2012-05-25 21:33:24
  • 3198

实现一个线程安全的内存池(使用线程私有数据机制TSD来实现)

本文只给出功能代码,后续文章进行内存池相关知识的简介。 #ifndef __BLUESKY_THREADSAFEMEMORY_H__ #define __BLUESKY_THREADSAFEMEM...
  • u012421852
  • u012421852
  • 2016-07-01 23:52:13
  • 503

linux线程私有数据详解

在单线程程序中,函数经常使用全局变量或静态变量,这是不会影响程序的正确性的,但如果线程调用的函数使用全局变量或静态变量,则很可能引起编程错误,因为这些函数使用的全局变量和静态变量无法为不同的线程保存各...
  • caoyan_12727
  • caoyan_12727
  • 2016-08-22 22:07:00
  • 1695

浅谈并发服务器---多线程并发---4(线程安全)

在多线程环经
  • zbq41409
  • zbq41409
  • 2014-07-24 18:48:45
  • 982

Thread-Specific Data(TSD)线程私有数据

一句话总结:线程共享一个全局变量key,但对应的value每个线程都有一份,互不影响。 表面上看起来这是一个全局变量,所有线程都可以使用它,而它的值在每一个线程中又是单独存储的,...
  • Nick_666
  • Nick_666
  • 2017-08-01 09:46:14
  • 184
收藏助手
不良信息举报
您举报文章:私有数据--TSD
举报原因:
原因补充:

(最多只允许输入30个字)