Code Bye

关于linux下线程本地存储的疑惑

 以下定义应用自:
http://blog.csdn.net/cywosp/article/details/26469435
在C/C++程序中常存在全局变量、函数内定义的静态变量以及局部变量,对于局部变量来说,其不存在线程安全问题,因此不在本文讨论的范围之内全局变量函数内定义的静态变量,是同一进程中各个线程都可以访问的共享变量,因此它们存在多线程读写问题。在一个线程中修改了变量中的内容,其他线程都能感知并且能读取已更改过的内容,这对数据交换来说是非常快捷的,但是由于多线程的存在,对于同一个变量可能存在两个或两个以上的线程同时修改变量所在的内存内容,同时又存在多个线程在变量在修改的时去读取该内存值,假如没有使用相应的同步机制来保护该内存的话,那么所读取到的数据将是不可预知的,甚至可能导致程序崩溃。
假如需要在一个线程内部的各个函数调用都能访问、但其它线程不能访问的变量,这就需要新的机制来实现,我们称之为Static memory local to a thread (线程局部静态变量),同时也可称之为线程特有数据(TSD: Thread-Specific Data)或线程局部存储(TLS: Thread-Local Storage)。这一类型的数据,在程序中每个线程都会分别维护一份变量的副本(copy),并且长期存在于该线程中,对此类变量的操作不影响其他线程。

本人的问题:
既然线程本地存储是针对全局变量和局部静态变量,为什么很多网上的例子都是针对的是线程的局部变量?
例如:http://blog.csdn.net/lwfcgz/article/details/37570667

/* 
 * ===================================================================================== 
 *       Filename:  thead.c 
 *    Description:  getspecific 
 *        Created:  05/10/2011 12:09:43 AM 
 * ===================================================================================== 
 */  
#include<stdio.h>  
#include<pthread.h>  
#include<string.h>  
pthread_key_t p_key;  
   
void func1()  
{  
        int *tmp = (int*)pthread_getspecific(p_key);//同一线程内的各个函数间共享数据。  
        printf("%d is runing in %s\n",*tmp,__func__);  
   
}  
void *thread_func(void *args)  
{  
   
        pthread_setspecific(p_key,args);  
   
        int *tmp = (int*)pthread_getspecific(p_key);//获得线程的私有空间  
        printf("%d is runing in %s\n",*tmp,__func__);  
   
        *tmp = (*tmp)*100;//修改私有变量的值  
   
        func1();  
   
        return (void*)0;  
}  
int main()  
{  
        pthread_t pa, pb;  
        int a=1;  
        int b=2;  
        pthread_key_create(&p_key,NULL);  
        pthread_create(&pa, NULL,thread_func,&a);  
        pthread_create(&pb, NULL,thread_func,&b);  
        pthread_join(pa, NULL);  
        pthread_join(pb, NULL);  
        return 0;  
}

这个代码里面a,b本身就是局部变量,传到线程两个线程后,也只是在线程本人的栈空间里,那为什么要使用线程本地存储这个方法了。

解决方案

40

你误解了 pthread_create 参数的意义。传入 &a 和 &b 是把这个指针作为 thread_func 的参数,pa/pb 在线程开始执行时就使用这个参数来调用 thread_func ,之后的 pthread_setspecific(p_key,args); 才开始使用线程本地储存。
随着c++11/c11 开始引入 thread_local/_Thread_local 关键字,这些手动声明和使用TLS的代码或许也将离我们远去吧

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明关于linux下线程本地存储的疑惑