为了实现多个函数共享数据,可使用进程中的全局变量的方法,这样进程中的所有线程就都可以访问该数据,但有时为了使某数据只在某线程中共享,这样的方法显然不行,这时候我们就可以使用线程私有数据的方法实现,使用步骤如下:
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。另外,在线程执行完毕后,确实是执行了私有数据创建时的资源清理函数,参数也是该线程关联的数据。