进程内的全部线程共享进程的数据空间,因此全局变量为全部线程共有。在某些场景下,线程须要保存本身的私有数据,这时能够建立线程私有数据(Thread-specific Data)TSD来解决。在线程内部,私有数据能够被线程的各个接口访问,但对其余线程屏蔽。linux
线程私有数据采用了一键多值技术,及一个key对应多个值。访问数据都是经过键值来访问的。数组
使用线程私有数据时,须要对每一个线程建立一个关联 的key,linux中主要有四个接口来实现:app
一、pthread_key_create:建立一个键函数
int pthread_key_create(pthread_key_t *key, void (*destr_function) (void*));
首先从linux的TSD池中分配一项,而后将其值赋给key供之后访问使用。接口的第一个参数是指向参数的指针,第二参数是函数指针,若是该指针不为空,那么在线程执行完毕退出时,已key指向的内容为入参调用destr_function(),释放分配的缓冲区以及其余数据。ui
key被建立以后,由于是全局变量,因此全部的线程均可以访问。各个线程能够根据需求往key中,填入不一样的值,这就至关于提供了一个同名而值不一样的全局变量,即一键多值。一键多值依靠的一个结构体数组,即spa
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。code
二、pthread_setspecific:为指定键值设置线程私有数据blog
int pthread_setspecific(pthread_key_t key, const void *pointer);
该接口将指针pointer的值(指针值而非其指向的内容)与key相关联,用pthread_setspecific为一个键指定新的线程数据时,线程必须释放原有的数据用以回收空间。
三、pthread_getspecific:从指定键读取线程的私有数据
void * pthread_getspecific(pthread_key_t key);
四、pthread_key_delete:删除一个键
void * pthread_getspecific(pthread_key_t key);
该接口用于删除一个键,功能仅仅是将该key在结构体数组pthread_keys对应的元素设置为“un_use”,与改key相关联的线程数据是不会被释放的,所以线程私有数据的释放必须在键删除以前。