论坛首页 编程语言技术论坛

Linux C中也有“ThreadLocal”

浏览 7932 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-07-09  
这个东东有一定的历史,说起来话长,
高效TLS的设计在以前硬件不支持的时候比较麻烦,
后来专门有线程寄存器来做这个事情。
看这段代码
static inline struct _TEB * NtCurrentTeb(void)
{
struct _TEB * pTeb;
__asm mov eax, fs:0x18
__asm mov pTeb, eax
return pTeb;
}
这里存放的是每个线程的数据,

最早以前的实现可能是放一个映射表,切换线程的时候来查找。
要不你得根据TID来自己进行TLS的数据查找,显然效率不快。其实也不能完全说硬件支持,但软件支持的TLS效率显示不高。
0 请登录后投票
   发表时间:2008-07-09  
这里面主要是fs这个后来引入的寄存器造成的。
linux有关nptl的设计文档里提到了这一点。
0 请登录后投票
   发表时间:2008-07-09  
int pthread_setspecific(pthread_key_t key, const void * pointer)
{
  pthread_descr self = thread_self();
  unsigned int idx1st, idx2nd;

  if (key >= PTHREAD_KEYS_MAX || !pthread_keys[key].in_use)
    return EINVAL;
  idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
  idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
  if (THREAD_GETMEM_NC(self, p_specific[idx1st]) == NULL) {
    void *newp = calloc(PTHREAD_KEY_2NDLEVEL_SIZE, sizeof (void *));
    if (newp == NULL)
      return ENOMEM;
    THREAD_SETMEM_NC(self, p_specific[idx1st], newp);
  }
  THREAD_GETMEM_NC(self, p_specific[idx1st])[idx2nd] = (void *) pointer;
  return 0;
}

这是一个大概的实现,
pthread_descr self = thread_self();
这里基本上就是取得线程的私有化数据。
至于其他语言的,WIN平台上的实现就不用提了,基本上是调WINAPI,linux平台上的实现基本上是调用pthread来实现的。pthread调用了不少的系统API来实现这一点。

当然,语言本身也可以进行一定的模拟。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics