您的位置:首页 > 运维架构 > Linux

Linux线程私有数据pthread_key_t

2014-01-14 17:16 375 查看
转至:http://blog.163.com/william_djj@126/blog/static/3516650120085111193035/

#include <pthread.h>

函数原型:

int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));

参数说明:

第一个参数为指向一个键值的指针,第二个参数指明了一个destructor函数,如果这个参数不为空,那么当每个线程结束时,系统将调用这个函数来释放绑定在这个键上的内存块。

函数原型:

int pthread_key_delete(pthread_key_t key);

作用:

注销一个TSD,这个函数并不检查当前是否有线程正使用该TSD,也不会调用清理函数(destr_function),而只是将TSD释放以供下一次调用pthread_key_create()使用。

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

void *pthread_getspecific(pthread_key_t key);

set是把一个变量的地址告诉key,一般放在变量定义之后,get会把这个地址读出来,然后你自己转义成相应的类型再去操作,注意变量的有效期。只不过,在不同的线程里可以操作同一个key,他们不会冲突,比如线程a,b,c set同样的key,分别get得到的地址会是之前各自传进去的值。这样做的意义在于,可以写一份线程代码,通过key的方式多线程操作不同的数据。


*-----------------------------pthread_private_data.c--------------------------------------*/

/*三个线程:主线程,th1,th2各自有自己的私有数据区域

*/

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <pthread.h>

static pthread_key_t str_key;

//define a static variable that only be allocated once

static pthread_once_t
str_alloc_key_once=PTHREAD_ONCE_INIT;

static void str_alloc_key();

static void str_alloc_destroy_accu(void*
accu);

char* str_accumulate(const char*
s)

{ char*
accu;

pthread_once(&str_alloc_key_once,str_alloc_key);//str_alloc_key()这个函数只调用一次

accu=(char*)pthread_getspecific(str_key);//取得该线程对应的关键字所关联的私有数据空间首址

if(accu==NULL)//每个新刚创建的线程这个值一定是NULL(没有指向任何已分配的数据空间)

{ accu=malloc(1024);//用上面取得的值指向新分配的空间

if(accu==NULL) return NULL;

accu[0]=0;//为后面strcat()作准备

pthread_setspecific(str_key,(void*)accu);//设置该线程对应的关键字关联的私有数据空间

printf("Thread %lx:
allocating buffer at %p\n",pthread_self(),accu);

}

strcat(accu,s);

return accu;

}

//设置私有数据空间的释放内存函数

static void str_alloc_key()

{ pthread_key_create(&str_key,str_alloc_destroy_accu);/*创建关键字及其对应的内存释放函数,当进程创建关键字后,这个关键字是NULL。之后每创建一个线程os都会分给一个对应的关键字,关键字关联线程私有数据空间首址,初始化时是NULL*/

printf("Thread %lx:
allocated key %d\n",pthread_self(),str_key);

}

/*线程退出时释放私有数据空间,注意主线程必须调用pthread_exit()(调用exit()不行)才能执行该函数释放accu指向的空间*/

static void str_alloc_destroy_accu(void*
accu)

{ printf("Thread %lx:
freeing buffer at %p\n",pthread_self(),accu);

free(accu);

}

//线程入口函数

void* process(void *arg)

{ char*
res;

res=str_accumulate("Resule of ");

if(strcmp((char*)arg,"first")==0)

sleep(3);

res=str_accumulate((char*)arg);

res=str_accumulate(" thread");

printf("Thread %lx: \"%s\"\n",pthread_self(),res);

return NULL;

}

//主线程函数

int main(int argc,char*
argv[])

{ char*
res;

pthread_t th1,th2;

res=str_accumulate("Result of ");

pthread_create(&th1,NULL,process,(void*)"first");

pthread_create(&th2,NULL,process,(void*)"second");

res=str_accumulate("initial thread");

printf("Thread %lx: \"%s\"\n",pthread_self(),res);

pthread_join(th1,NULL);

pthread_join(th2,NULL);

pthread_exit(0);

}

/*------------------------------------------------------------------*/

[root@10h57 c]# ./pthread_private_data

Thread b7fdd6c0 : allocated key 0

Thread b7fdd6c0: allocating buffer at 0x911c008

Thread b7fdd6c0: "Result of initial thread"

Thread b7fdcb90: allocating buffer at 0x911c938

Thread b75dbb90: allocating buffer at 0x911cd40

Thread b75dbb90: "Resule of second thread"

Thread b75dbb90: freeing buffer at 0x911cd40

Thread b7fdcb90: "Resule of first thread"

Thread b7fdcb90: freeing buffer at 0x911c938

Thread b7fdd6c0: freeing buffer at 0x911c008

重入函数str_accumulate()里动态分配内存,这些动态分配的空间是线程的私有数据,只对本线程可见(对主线程也不看见)。通过这种技术实现了私有数据的私有分配和回收。(相当于用类的思想实现私有数据的分配和回收,可见线程库向面向对象发展的趋势是必然的)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: