linux线程私有数据---TSD池,linux---tsd


      进程内的所有线程共享进程的数据空间,所以全局变量为所有线程共有。在某些场景下,线程需要保存自己的私有数据,这时可以创建线程私有数据(Thread-specific Data)TSD来解决。在线程内部,私有数据可以被线程的各个接口访问,但对其他线程屏蔽。

      线程私有数据采用了一键多值技术,及一个key对应多个值。访问数据都是通过键值来访问的。

   使用线程私有数据时,需要对每个线程创建一个关联 的key,linux中主要有四个接口来实现:

1、pthread_key_create:创建一个键

int pthread_key_create(pthread_key_t *key, void (*destr_function) (void*));

首先从linux的TSD池中分配一项,然后将其值赋给key供以后访问使用。接口的第一个参数是指向参数的指针,第二参数是函数指针,如果该指针不为空,那么在线程执行完毕退出时,已key指向的内容为入参调用destr_function(),释放分配的缓冲区以及其他数据。

key被创建之后,因为是全局变量,所以所有的线程都可以访问。各个线程可以根据需求往key中,填入不同的值,这就相当于提供了一个同名而值不同的全局变量,即一键多值。一键多值依靠的一个结构体数组,即

static struct pthread_key_struct pthread_keys[PTHREAD_KEYS_MAX] ={{0,NULL}};

pthread_key_struct 的定义为:

struct pthread_key_struct
{
  /* Sequence numbers.  Even numbers indicated vacant entries.  Note
     that zero is even.  We use uintptr_t to not require padding on
     32- and 64-bit machines.  On 64-bit machines it helps to avoid
     wrapping, too.  */
  uintptr_t seq;

  /* Destructor for the data.  */
  void (*destr) (void *);
};

PTHREAD_KEYS_MAX值为1024

创建一个TSD,相当于将结构体数组的某一个元素的seq值设置为为“in_use”,并将其索引返回给*key,然后设置destr_function()为destr()。pthread_key_create创建一个新的线程私有数据key时,系统会搜索其所在进程的key结构数组,找出一个未使用的元素,将其索引赋给*key。

2、pthread_setspecific:为指定键值设置线程私有数据

int pthread_setspecific(pthread_key_t key, const void *pointer);

该接口将指针pointer的值(指针值而非其指向的内容)与key相关联,用pthread_setspecific为一个键指定新的线程数据时,线程必须释放原有的数据用以回收空间。

3、pthread_getspecific:从指定键读取线程的私有数据

void * pthread_getspecific(pthread_key_t key);

4、pthread_key_delete:删除一个键

void * pthread_getspecific(pthread_key_t key);

该接口用于删除一个键,功能仅仅是将该key在结构体数组pthread_keys对应的元素设置为“un_use”,与改key相关联的线程数据是不会被释放的,因此线程私有数据的释放必须在键删除之前。


怎在VC多线程下使用私有的全局变量

貌似没有很好的办法。只有为函数增加一个参数(指针或引用,一个变量的话可以引用,多个就只能用指针了),在线程中定义变量并将变量传入。
 

linux下进程与线程的同步问题

同一个进程内的线程之间共享地址空间,因此共享全局变量,所以在一个线程中修改,对其它线程是可见的。

线程私有的包括:堆栈、指令、寄存器和线程私有数据。
 

相关内容

    暂无相关文章