精华帖 (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效率显示不高。 |
|
返回顶楼 | |
发表时间:2008-07-09
这里面主要是fs这个后来引入的寄存器造成的。
linux有关nptl的设计文档里提到了这一点。 |
|
返回顶楼 | |
发表时间: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来实现这一点。 当然,语言本身也可以进行一定的模拟。 |
|
返回顶楼 | |