zoukankan      html  css  js  c++  java
  • posix多线程--线程私有数据

    1.当多个线程共享一个变量时,将该变量定义为静态或外部变量,使用互斥量确保共享变量的安全访问。
    如果每个线程都需要一个私有变量值,则该值成为线程的私有数据。程序创建一个键,每个线程独立地设定或得到自己的键值,各线程间私有数据互不影响。

    2.建立线程私有数据
    int pthread_key_create(pthread_key_t *key,void (*destructor)(void *));
    int pthread_key_delete(pthread_key_t key);
    int pthread_setspecific(pthread_key_t key,void *value);
    void *pthread_getspecific(pthread_key_t key);

    私有数据键,若多次创建,会覆盖掉前面创建的键,对应的键值也将永远丢失。

    使用pthread_key_delete释放一个私有数据键时,必须保证所有线程都不在持有该键的值。
    更好的做法是不释放线程私有数据键,因为线程私有数据键最多可达128个,很少有程序需要这么多的树木,没有必要手动释放。

    代码示例如下:
    创建数据键,设置键值,获取键值

    #include<stdio.h>                                                                
    #include<pthread.h>
    typedef struct tsd_tag
    {
            pthread_t tid;
            char *string;
    }tsd_t;
    pthread_key_t tsd_key;
    pthread_once_t key_once = PTHREAD_ONCE_INIT;
    void one_routine(void)
    {
            pthread_key_create(&tsd_key,NULL);;
    }
    void *thread_routine(void *arg)
    {
            pthread_once(&key_once,one_routine);
            tsd_t *value;
            value = (tsd_t*)malloc(sizeof(tsd_t));
            pthread_setspecific(tsd_key,value);
            value->tid = pthread_self();
            value->string = (char*)arg;
            value=(tsd_t*)pthread_getspecific(tsd_key);
            sleep(2);
            value=(tsd_t*)pthread_getspecific(tsd_key);
            printf("%s done...
    ",value->string);
    }
    int main(void)
    {
            pthread_t tid1,tid2;
            pthread_create(&tid1,NULL,thread_routine,"thread 1");
            pthread_create(&tid2,NULL,thread_routine,"thread 2");
            pthread_exit(NULL);
    }         
    View Code

    3.destructor函数
    destructor函数仅仅当线程终止时被调用。当线程终止时,pthreads调用键的destructor函数前,将线程私有数据置为NULL,所以若线程私有数据值是堆存储的地址,并且想在destructor函数中释放,必须使用传递给destructor的参数,而不是pthread_getspecific的参数。可以自定义destructor函数。

    键值为NULL意味着线程对应该键值不再有值,而不是赋空值。否则若随后调用pthread_key_create建立该键,线程将会收到旧值。

    线程私有数据键的destructor函数在键值替换的时候不会被调用。即,如果在堆中将一个结构的指针作为键值,又分配一个新结构,并将新结构指针赋给相同数据键,则指向旧结构的指针不会调用destructor函数。

    代码示例如下:

    三个线程的私有变量数据,自定义destructor函数,在线程结束后,释放堆存储,在所有线程结束后,销毁私有数据键。

    #include<stdio.h>                                                                
    #include<pthread.h>
    typedef struct private_tag
    {
            pthread_t tid;
            char *string;
    }private_t;
    pthread_key_t key;
    pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
    long counter = 0;
    void key_destructor(void *value)
    {
            private_t *private = (private_t*)value;
            printf("thread "%s" exiting...
    ",private->string);
            free(value);
            pthread_mutex_lock(&mutex);
            counter--;
            if(counter<=0)
            {
                    pthread_key_delete(key);
                    printf("key deleted...
    ");
            }
            pthread_mutex_unlock(&mutex);
    }
    void *key_get(void)
    {
            void *value;
            value = pthread_getspecific(key);
            if(value==NULL)
            {
    printf("malloc
    ");
    value = malloc(sizeof(private_t));
                    pthread_setspecific(key,(void*)value);
            }
            return value;
    }
    void *thread_routine(void *arg)
    {
            private_t *value;
            value = (private_t*)key_get();
            value->tid = pthread_self();
            value->string = (char*)arg;
            printf("thread "%s" starting...
    ",value->string);
            sleep(2);
            return NULL;
    }
    int main(void)
    {
            pthread_t tid1,tid2;
            private_t *value;
            pthread_key_create(&key,key_destructor);
            counter = 3;
            value = (private_t *)key_get();
            value->tid = pthread_self();
            value->string = "Main thread";
            pthread_create(&tid1,NULL,thread_routine,"Thread 1");
            pthread_create(&tid2,NULL,thread_routine,"Thread 2");
            printf("exiting
    ");
            pthread_exit(NULL);
    }                        
    View Code
  • 相关阅读:
    阿里云服务器完全卸载监控教程
    培养孩子专注力的10种方法
    多头数据分析
    腾讯分数分析报告-医美
    Omnibus test
    个股与指数的回归分析(自带python ols 参数解读)
    excel多元回归-系数参数解读
    比萨斜塔——统计显著性检验
    how to calculate the best fit to a plane in 3D, and how to find the corresponding statistical parameters
    sns.pairplot
  • 原文地址:https://www.cnblogs.com/shijingjing07/p/5404998.html
Copyright © 2011-2022 走看看