Linux 之多线程编程-私有数据(TSD)

为了实现多个函数共享数据,可使用进程中的全局变量的方法,这样进程中的所有线程就都可以访问该数据,但有时为了使某数据只在某线程中共享,这样的方法显然不行,这时候我们就可以使用线程私有数据的方法实现,使用步骤如下:
1、创建线程私有数据

#include 
int pthread_key_create(pthread_key_t* key,void (*func)(void*));

该函数将会从TSD池中分配一项,并将地址赋给key,共之后访问使用第1参数所关联的数据为参数调用其指向的资源释放函数。该函数在进程中调用一次即可,因为只要key被创建,其他的所有线程都是可以访问他的,而且每个线程往key里关联的数据都是相互独立,互不影响的,相对于一个同名不同值的全局变量。

2、向key中填入关联数据

#include 
int pthread_setspecific(pthread_key_t key,const void* pointer);

函数将数据pointer与key相关联。

3、从key中将关联数据读出

#include 
void* pthread_getspecific(pthread_key_t key);

函数将key所关联的数据读出并返回。

4、注销线程私有数据

#include 
int pthread_key_delete(pthread_key_t key);

直接将key关联的数据项为NULL,并将key释放,供下次创建使用。

事例代码如下:

#include 
#include 
#include  
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

pthread_key_t key;

void cleanup(void* t)
{
    int tid = pthread_self();
    printf("cleanup...........pid =%d,t=%s\n",tid,(char*)t);

}
void* test1(void)
{
    char str[1024] = "我是线程1维护的数据";
    char* pstr;
    int tid = pthread_self();

    printf("test1:str=%s,tid=%d\n",str,tid);
    pthread_setspecific(key,str);
        sleep(1);
    pstr = (char*)pthread_getspecific(key); 

    printf("test1:pstr=%s,tid=%d\n",pstr,tid);
    return;
}
void* test2(void)
{
    char str[1024] = "我是线程2维护的数据";
    char* pstr;
    int tid = pthread_self();

    printf("test2:str=%s,tid=%d\n",str,tid);
    pthread_setspecific(key,str);

    pstr = (char*)pthread_getspecific(key); 

    printf("test2:pstr=%s,tid=%d\n",pstr,tid);
    return;
}

int main()
{
    pthread_t pid1;
    pthread_t pid2;

    pthread_key_create(&key,cleanup);
    pthread_create(&pid1,NULL,(void*)test2,NULL);
    pthread_create(&pid2,NULL,(void*)test1,NULL);
    sleep(3);

    int tid = pthread_self();
    printf("main...........pid =%d\n",tid);
    pthread_join(pid1,NULL);
    pthread_join(pid2,NULL);
}

运行结果如下:

test1:str=我是线程1维护的数据,tid=-1227744448
test2:str=我是线程2维护的数据,tid=-1219351744
test2:pstr=我是线程2维护的数据,tid=-1219351744
cleanup...........pid =-1219351744,t=我是线程2维护的数据
test1:pstr=我是线程1维护的数据,tid=-1227744448
cleanup...........pid =-1227744448,t=我是线程1维护的数据
main...........pid =-1219348736

从结果可以看出,线程1先关联数据后,再让线程2关联数据,再将线程1关联的数据打印出来,发现线程2的修改并不影响线程1。另外,在线程执行完毕后,确实是执行了私有数据创建时的资源清理函数,参数也是该线程关联的数据。

你可能感兴趣的:(Linux)