【C/C++多线程编程之十】pthread线程私有数据

多线程编程之线程私有数据

     Pthread POSIX threads 的简称,是POSIX线程标准

        线程同步从互斥量C/C++多线程编程之六】pthread互斥量信号量C/C++多线程编程之七】pthread信号量,条件变量C/C++多线程编程之八】pthread条件变量,读写锁C/C++多线程编程之九】pthread读写锁多线程的同步机制已经有了清晰深入的探究,多线程编程的精髓所在,需要深入理解。

       线程私有数据TSD(Thread-specific Data),在【C/C++多线程编程之五】pthread线程深入理解中有提及,进程全局变量是被所有线程共享的,处于功能与安全的需求,有必要为线程提供线程全局变量。线程全局变量便是线程私有数据,仅在某个线程内有效。

       

            1. 线程私有数据

        线程私有数据通过关联的键值key识别,创建时将私有数据与key关联,通过key向线程私有数据写入内容,也通过key读取线程私有数据的内容,最后通过key 删除线程私有数据。 

        线程私有数据创建后,该进程内所有的线程都可以使用这个key向线程私有数据写入与读取数据。对不同的线程而言,同一个key值,分别访问线程自己的私有数据,互不影响。

        举例:

        创建关联key的线程私有数据后,每个线程都有一份对应的线程私有数据。

        线程A通过key访问线程A中的对应的线程私有数据。

        线程B通过key访问线程B中的对应的线程私有数据。

        2.线程私有数据基本函数

        #include<pthread.h>

创建线程私有数据

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

        该函数的第一个参数为键值key,第二个参数为销毁函数(一般设为NULL,不为空时,销毁线程私有数据时,会调用该函数以释放分配的内存)。

写入数据

        int pthread_setspecific(pthread_key_t  key,  void  *pointer);

        该函数的第一个参数为键值key,第二个参数为写入数据指针(该指针类型为void* ,可以写入指向任何数据类型的指针)。pointer写入的是这个指针的值,而不是pointer指向的内容。

读取数据

        void * pthread_getspecific(pthread_key_t key);

        该函数的参数为键值key,返回写入的数据。如果线程没有写入数据,则返回空指针。child3验证)

销毁线程私有数据

        int pthread_key_delete(pthread_key_t key);

        该函数的参数为键值key,用于销毁线程私有数据。

        3.牛刀小试:

        线程child1,child2均把自己的线程ID写入自己的线程私有数据中,写入的是一个指针,在读出的数据是void *型的指针,需要对其进行强制类型转换。

 

 

#include "pthread.h"

#include "sched.h"

#include "semaphore.h"

#include "stdio.h"

#include "windows.h"

 

#pragma comment(lib, "pthreadVC2.lib")     //必须加上这句

 

pthread_key_t   key;

 

pthread_t tid1,*p1;

pthread_t tid2,*p2;

pthread_t tid3, *p3;

 

void * child1(void *arg)

{

p1=&tid1;

 

pthread_setspecific(key,p1);       //将线程id写入线程私有数据

 

p1=(pthread_t *)pthread_getspecific(key);   //读取线程私有数据

 

printf("线程child1 的私有数据: %d\n",*p1);

return NULL;

}

 

void * child2(void *arg)

{

p2=&tid2;

 

pthread_setspecific(key,p2);       //将线程id写入线程私有数据

 

p2=(pthread_t *)pthread_getspecific(key);    //读取线程私有数据

 

printf("线程child2的私有数据:%d\n",*p2);

 

Sleep(500);

 

return NULL;

}

 

// 不写数据 直接读 测试

void *child3(void *arg)

{

p3 = (pthread_t *)pthread_getspecific(key); // 发现读出来的为空指针

 

if (p3 == NULL)

{

printf("p3 is null.\n");

}

else

{

printf("现场childtest的私有数据:%d", *p3);

}

 

Sleep(100);

 

return NULL;

}

 

 

int main(void)

{

pthread_key_create(&key,NULL);      //创建线程私有数据

 

pthread_create(&tid1,NULL,child1,NULL);

pthread_create(&tid2,NULL,child2,NULL);

pthread_create(&tid3, NULL, child3, NULL);

 

Sleep(100000);

 

pthread_key_delete(key);            //销毁线程私有数据

return 0;

}

 

来自 <https://blog.csdn.net/lovecodeless/article/details/24983131>

猜你喜欢

转载自blog.csdn.net/zcc1229936385/article/details/81231177