线程私有数据的介绍与使用(TSD)

                            线程私有数据的介绍与使用(TSD)

       创始线程私有数据就是为了线程内部各个函数可以很容易的传递数据信息,因此要使线程外的函数不能访问这些数据,而线程内的函数使用这些数据就像线程内的全局变量一样,这些数据在一个线程内部是全局的,一般用线程私有数据的地址作为线程内各个函数访问该数据的入口。

POSIX系统要求每个进程有一个Key(键值)结构数组,这个结构体数组至少包含128个元素,每个元素至少包含两项内容,分别是这个元素的使用标志(这个元素是否被使用了)和这个元素的析构函数的指针,使用标志初始值是未被使用。每个元素(键值)是一个进程的全局变量,所有线程都可以使用该元素(键值),通过以下函数生成该键值:

pthread_key_t key;(一个键值类型的变量)

pthread_key_creat(pthread_key_t * ptr_key, void ( *destruction)(void *arg))

该函数成功完成之后返回0,其他任何返回值都表明错误,例如:EAGAIN:名称空间已用完;ENOMEM:进程中虚拟内存不足,无法创建新键;

如果一个系统的Key结构数组包含128个元素,那么每个元素的索引从0到127就是这个键值,那么上面这个函数搜索其所在进程的这个结构数组,知道找到第一个未被使用的键,将这个键值作为值参传递给上述函数的第一个参数,同时注册该键值的析构函数,当某个线程对这个键值关联了自己的线程私有数据时,当这个线程正常退出时(调用pthread_exit()),就会调用该析构函数,析构函数的作用一般是释放该线程私有数据所占据的内存单元,不然就会出现内存泄露的情况。

每个线程内部的数据在进程中由一个Pthread的数据结构来维护,其中包括了每个线程的私有数据TSD,Pthread结构中包含名为pkey的指针数组,也是一个包含128个元素的数组,初始值为空(NULL),这128个指针与Key结构数组里面的128个元素一一对应,(因此,从理论上说每个线程可以有128个线程私有数据,自己这么认为的),在调用pthread_key_creat()得到一个键之后,每个线程可以依据这个键操作自己的Pkey数组中对应的指针(也就是线程私有数据的地址),这通过int pthread_setspecific(pthread_key_t key, const void *value);void *pthread_getspecific(pthread_key_t key);两个函数来实现。pthread_setspecific函数将与key对应的Pkey指针数组中的值设为value,就像将这个线程私有数据的地址(value)绑定到该key上,如果不是第一次绑定到该键值,一定要先释放原来的TSD,然后再绑定该键到下一个TSD;pthread_getspecific()函数将key对应的Pkey中对应的指针数组的值返回作为该函数的返回值。

值得注意的是:相同的关键字在可以被进程里所有的线程所使用,但是每个线程都将关键字绑定到自己的线程私有数据上面,创建一个关键字时,每个线程对应的Pkey数组中的对应元素的值都初始化NULL,直到调用pthread_setspecific初始化绑定之后。

当你想把进程中的全局键(key)销毁时,可以调用pthread_key_delete(pthread_key_t key),该函数会直接销毁该键,并且也会相应的销毁与这个键对应的进程中所有线程的TSD,此外,该函数调用时不会检查是否有线程正在使用该键对应的线程的TSD,因此,在调用该函数之前最好先调用析构函数释放TSD分配的内存空间。也就是说最好将该函数调用放在主线程中,而其他初始化了TSD的线程在调用pthread_exit()的时候释放TSD,最后主线程再调用pthread_key_delete()结束。

 

线程的析构函数一般用来释放分配的TSD的内存空间,是通过destructive(void *arg)这里的arg参数来传递的,arg就等同于函数pthread_setspecific(pthread_key_t key,void *value)里的value值。也就是线程私有数据的地址,记住在value前面最好不要加地址,否则从析构函数出获取该TSD时会出错。

 

 

最后本文参考了链接中的文章以及其它的文章:http://xingyunbaijunwei.blog.163.com/blog/static/76538067201292911231312/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值