设为首页 加入收藏

TOP

10.5.2 线程相关的数据/线程局部存储
2013-10-07 15:05:17 来源: 作者: 【 】 浏览:70
Tags:10.5.2 线程 相关 数据 局部 存储

10.5.2  线程相关的数据/线程局部存储

PTHREADS和Win32线程基础设施都提供了某种程度上的TSS。PTHREADS[Bute1997]中的版本称为线程相关数据(TSD,Thread-Specific Data),Win32上的版本则被称为线程局部存储(TLS,Thread-Local Storage),它们的意思是一样的。

它们都提供某种方式来创建这样一个变量,该变量在进程中的每个使用它的线程中都具有不同的值。在PTHREADS里,该值被称为键(key),而在Win32上则被称为索引(index)。Win32把用于存放各线程中的键值的内存位置称为槽位(slot)。我喜欢键、槽位和值这3种说法。

PTHREADS的TSD基于如下的4个库函数:

  1. int pthread_key_create(    pthread_key_t  *key  
  2.                           ,    void (*destructor)(void *));  
  3. int pthread_key_delete(    pthread_key_t  key);  
  4. void *pthread_getspecific( pthread_key_t  key);  
  5. int pthread_setspecific(   pthread_key_t  key  
  6.                             ,   const void     *value);  
  7.  

pthread_key_create()创建了pthread_key_t类型的一个键(不透明类型)。调用者还可以传递一个清理函数,待会我们会讨论这个函数。通过调用pthread_setspecific()和pthread_getspecific()可以线程相关地设置或获取值。pthread_key_delete()则被用来销毁不再被需要的键。

Win32的TLS API具有类似的"四大金刚":

  1. DWORD  TlsAlloc(void);  
  2. LPVOID TlsGetValue(DWORD dwTlsIndex);  
  3. BOOL   TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue);  
  4. BOOL   TlsFree(DWORD dwTlsIndex);  

这些TSS API的常规用法是这样的:在主线程中,在任何其他线程活动之前,创建一个键,并将该键保存在一个公共地点(全局变量,或者通过某个函数返回),然后所有线程就可以通过从它们各自的槽位中存入或获取值,来操纵它们各自的TSS数据的拷贝。

遗憾的是,在这些模型中存在着若干不足,尤其是Win32的版本。

首先,这些API所能提供的键的数目有限。PTHREADS保证至少有128个,Win32则是64个。1尽管实际上人们很少会超过这个限度,但考虑到软件的多组件特征日益明显,要求更多键的可能性并非一点都没有。

第二个问题是Win32 API并没有提供任何在线程退出时清理槽位的能力。这意味着人们某种程度上必须能够拦截线程的退出,并借机清理与该线程的槽位中的值相关的资源。当然,对于C++(www.cppentry.com)用户而言,语言本身提供了自动析构机制,可以使我们免受这方面的痛苦,而且在某些场合非这种方式不能如愿。

尽管PTHREADS提供了在线程终止时清理资源的手段,但是它仍然没有提供完整的简单正确的资源处理机制。从本质上说,PTHREADS提供了常性(immutable)RAII(见3.5.1小节)。尽管这相对于Win32缺乏任何RAII是一个极大的改进,但有时候确实需要改变给定键对应的槽位值的能力。手工清理原先的值也是可行的,但是如果这种能力是自动的话要好得多。

第四个问题是,PTHREADS假定清理函数在清理点是可调用的。如果在某个线程退出时,它的清理函数将要(直接或间接)调用的API已经被反初始化(uninitialized)了,那么对该清理函数的调用就可能是无效的。类似的一个情况,甚至可算是实践中更常见的情况是,如果清理函数是位于动态库中的,那么此时该清理函数可能已经不再存在于进程的地址空间中了,而这则意味着进程崩溃。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇10.5.3 declspec(thread)和TLS 下一篇10.5.4 Tss库(1)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: