zoukankan      html  css  js  c++  java
  • 线程特定数据

    线程特定数据:
    在单线程程序中,我们经常要用到“全局变量”以实现多个函数间共享数据。在多线程环境下,由于数据空间是共享的,因此
    全局变量也为所有的线程所共享。但有的应用程序设计中有必要提供线程私有的全局变量,仅在某个线程中有效,但却可以跨越多个函数
    访问。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;
    }
  • 相关阅读:
    Palindrome Linked List 解答
    Word Break II 解答
    Array vs Linked List
    Reverse Linked List II 解答
    Calculate Number Of Islands And Lakes 解答
    Sqrt(x) 解答
    Find Median from Data Stream 解答
    Majority Element II 解答
    Binary Search Tree DFS Template
    188. Best Time to Buy and Sell Stock IV
  • 原文地址:https://www.cnblogs.com/wsw-seu/p/8497169.html
Copyright © 2011-2022 走看看