线程私有数据

        线程私有数据同其名字一样,表示在多线程里面,线程可以有仅属于自己的数据。这个数据往往是动态申请的堆空间(因为栈空间本身就是私有的,全局变量肯定对所有线程可见)。

        线程通过pthread_setspecific函数设置(存放)自己的私有变量,然后可以通过pthread_getspecific函数获取自己的私有变量。

        可能有人会疑问,既然自己动态申请了空间(就是说自己知道了这个指向堆空间的指针)。那么何必放到pthread_setspecific函数中由系统保存,之后又通过pthread_getspecific获取。这样做多此一举。其实,还是有一些情况需要用到这两个函数的。比如,有多个线程都会调用函数A, 并且在函数A中动态申请(调用malloc函数)线程的私有数据,然后通过pthread_setspecific保存起来。之后,这些线程都会调用B函数。在B函数中,必须获取这些属于线程私有的数据,然后根据不同的线程对这些私有数据做不同的事。


        由于一个线程可能会有多个不同的私有数据,所以使用了一个pthread_key_t类型的键值,其使得不同的键值对应同一个线程的不同私有数据。所以pthread_getspecific函数的原型为:

//返回值:线程的私有数据。如果没有数据与该键关联,则返回NULL
void* pthread_getspecific(pthread_key_t key);

        pthread_setspecific函数的原型为:

      //返回值:若成功,返回0,否则返回错误编号
       int pthread_setspecific(pthread_key_t key, const void* value);

        pthread_key_t 类型的键值通过pthread_key_create函数获得,销毁一个键值,使用函数pthread_key_delete。这两个函数的原型分别为:

       //两个函数都是成功时返回0, 失败时返回错误编号
       int pthread_key_create(pthread_key_t* keyp, void (*destructor)(void*) );
       int pthread_key_delete(pthread_key_t* key);

         pthread_key_create函数的第二个参数是一个函数指针,表示析构函数。该析构函数由系统自己调用,用户不用显示调用。当线程调用pthread_exit或者线程执行了return 返回时,析构函数就会自动被调用。但线程使用exit、_exit、_Exit、abort或者出现其他非正常退出时,析构函数不会被系统调用。

       析构函数的参数是一个void*类型。调用的时候,系统将pthread_setspecific函数中的第二个参数值传给它。如果pthread_setspecific的第二个参数是由malloc函数返回的堆空间指针,并且析构函数是free函数。那么系统将自动为我们释放内存。代码如下:

       pthread_key_t key;    //全局变量
 
       int pthread_key_create(&key, free);
       char* p = (char*)malloc( 100);
       pthread_setspecific(&key, p);

        当线程调用pthread_exit退出时,系统将自动为我们调用free(p); 释放堆空间。

        这里还有一个问题就是,pthread_key_t key是全局变量。如果像前面所讲的那样,线程分别调用A函数和B函数。此时键值必须是全局变量。

 

        另外,也是很重要的。同一个键值可以由多个线程所共享。某一个线程调用pthread_key_create创建一个键,其他线程都可以使用这个键。这样,不同的线程使用同一个键值,调用pthread_getspecific(key)函数,会得到不同的值。如果一个线程想拥有多个不同的线程私有数据,那么就应该申请多几个键值。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值