• 线程特定数据


    线程特定数据:
    在单线程程序中,我们经常要用到“全局变量”以实现多个函数间共享数据。在多线程环境下,由于数据空间是共享的,因此
    全局变量也为所有的线程所共享。但有的应用程序设计中有必要提供线程私有的全局变量,仅在某个线程中有效,但却可以跨越多个函数
    访问。POSIX线程库通过维护一定的数据结构来解决这个问题。
    //每个线程都有这个key。但是指向的数据不是共享的,是特定的数据。
    int pthread_key_create(pthread_key_t *keyp,void (*destructor)(void*));
    取消键与线程特定数据的关联
    int pthread_key_delete(pthread_key_t key);

    只要有一个线程创建了一个key,那么所有的线程就都有了一个key.假设线程0创建了key[1],其他线程也得到了一个key[1],
    每个线程都有一个key,但是每个线程的key都指向了每个线程特定的数据。

    //获取或者设定线程特定数据
    void* pthread_getspecific(pthread_key_t key);
    int pthread_setspecific(pthread_key_t key,const void* value);

    //把键和线程特定数据关联起来
    void* pthread_getspecific(pthread_key_t key);
    int pyhread_setspecific(pthread_key_t,const void* value);


    pthread_once_t initflag=PTHREAD_ONCE_INIT 必须是一个全局变量或者静态变量
    int pthread_once(pthread_once_t* initflag,void (*initfn)(void)) 第二个参数:函数的执行只在第一个线程中执行

    #include<unistd.h>
    #include<sys/types.h>
    #include<fcntl.h>
    #include<sys/stat.h>
    #include<stdlib.h>
    #include<stdio.h>
    #include<errno.h>
    #include<pthread.h>
    #include<string.h>
    #define ERR_EXIT(m)
        do
        {
            perror(m);
            exit(EXIT_FAILURE);
        }while(0)
    pthread_key_t  key_std;
    pthread_once_t initflag=PTHREAD_ONCE_INIT;//设置一个全局变量用于pthread_once
    //线程特定数据,自己设定,一个是线程ID,一个是指针。
    typedef struct tsd
    {
        pthread_t tid;
        char* str;
    }tsd_t;
    //线程特定数据销毁函数,每个线程都调用
    void destroy_routine(void* value)
    {
        printf("destroy ...
    ");
        free(value);
    }
    void once_routine(void)
    {
        pthread_key_create(&key_std,destroy_routine);//创建一个key.第二个参数是一个函数指针,表示如何销毁这个线程特定数据。
        printf("key init...
    ");
    }
    //线程入口函数中调用once_routine来创建键值。每次创建新线程,都会进入线程入口函数,调用once_routine
    //但是使用了pthread_once的话 ,只会执行一个once_routine。
    void * thread_routine(void* arg)
    {
        //如果我们把创建键值放到线程执行函数中,则需要调用pthread_once使得该键值创建只要执行一次
        
        pthread_once(&initflag,once_routine);
    
    
        tsd_t *value=(tsd_t*)malloc(sizeof(tsd_t));
        //构造线程特定数据
        value->tid=pthread_self();
        value->str=(char*)arg;
        //设置线程特定数据
        pthread_setspecific(key_std,value);
        printf("%s setsepecific %p
    ",(char*)arg,value);//%p指针值
        //通过key,获取设定的特定数据。
        value=pthread_getspecific(key_std);
        printf("tid=0x%x str=%s
    ",(int)value->tid,value->str);
        //2个线程都到这睡眠。数据不会串改
        sleep(2);
        printf("tid=0x%x str=%s
    ",(int)value->tid,value->str);
        return NULL;
    }    
    int main(void)
    {
        // pthread_key_create(&key_std,destroy_routine);//每个线程退出都会调用destroy_routine。销毁两次
        //每个线程都有这个key,但各自的值不同
        pthread_t tid1;
        pthread_t tid2;
        pthread_create(&tid1,NULL,thread_routine,"thread1");
        pthread_create(&tid2,NULL,thread_routine,"thread2");//每个线程结束,都会调用destroy_routine。
        
        pthread_join(tid1,NULL);
        pthread_join(tid2,NULL);
        //线程结束删除key
        pthread_key_delete(key_std);
    
        return 0;
    }
  • 相关阅读:
    Django + Vue cli 3.0 访问静态资源问题
    服务器宕机,mysql无法启动,job for mysql.service failed because the process exited with error code,数据库备份与恢复
    Git 深度学习填坑之旅三(分支branch、远程操作)
    Git 深度学习填坑之旅二(文件三种状态、打标签)
    2017-2018学年校历
    gson
    Android adb.exe程序启动不起来,如何处理
    Android LayoutInflater详解
    android genymation eclipse安装
    视频
  • 原文地址:https://www.cnblogs.com/wsw-seu/p/8497169.html
Copyright © 2020-2023  润新知