码迷,mamicode.com
首页 > 编程语言 > 详细

线程特定数据

时间:2014-11-14 14:17:28      阅读:286      评论:0      收藏:0      [点我收藏+]

标签:pthread   线程特定数据   c   多线程   

在多线程程序里,我们有可能经常遇到因为函数使用的静态变量无法为不同的线程保存各自的值的问题。有很多办法可以解决,本文就来看一下通过线程特定数据来解决这样的问题。

每个系统支持有限的线程特定数据元素。POSIX要求这个限制不小于128(每个进程)。系统为每个进程维护一个我们称之为key结构的结构数组,如图:bubuko.com,布布扣

key结构中的标志指示这个数据元素是否正在使用,所有的标志初始化为“不在使用”。当一个线程调用pthread_key_create创建一个新的线程特定数据元素时,系统会返回第一个不在使用的元素。key结构中的析构函数指针,当一个线程终止时,系统将扫描该线程的pkey数组,为每个非空的pkey指针调用相应的析构函数。

除了进程范围的key结构数组外,系统还在进程内维护关于每个线程的多条信息。这些特定于线程的信息我们称之为pthread结构,其部分内容是我们称之为pkey数组的一个128个元素的指针数组。如图:

bubuko.com,布布扣

注意当我们调用pthread_key_create创建一个键时,系统告诉我们这个键。每个线程可以随后为该键存储一个值(指针),而这个指针通常是每个线程通过malloc获得的。

具体的函数如下:

#include <pthread.h>
int pthread_once(pthread_once_t *onceptr, void (*init)(void));
int pthread_key_create(pthread_key_t *keyptr, void (*destructor)(void *value));

void *pthread_getspecific(pthread_key_t key);
int pthread_setspecific(pthread_key_t key, const void *value);
使用用例:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

pthread_key_t rl_key;
pthread_once_t rl_once = PTHREAD_ONCE_INIT;

void destructor(void *value) {
    printf("pthread:%d destructor value(%p)\n", pthread_self(), value);
    free(value);// 线程结束后执行
}

void create_key() {
    pthread_key_create(&rl_key, destructor);// 申请一个key
    printf("pthread:%d create_key %d\n", pthread_self(), rl_key);
}

void *foo(void *param) {
    int i;
    for(i = 0; i < 2; i++) {
    pthread_once(&rl_once, create_key); // 只运行一次create_key

    void *ptr;
    if ( (ptr = pthread_getspecific(rl_key)) == NULL) {// 检查当前线程key域是否有值
        ptr = malloc(10);
        pthread_setspecific(rl_key, ptr);// 设置key的值
        printf("pthread:%d key(%d) value(%p)\n", pthread_self(), rl_key, ptr);
    }
    }
}

int main(void)
{
    pthread_t t[5];
    int i;
    for(i = 0; i < 5; i++) {
        pthread_create(&t[i], NULL, foo, NULL);
    }


    for(i = 0; i < 5; i++) {
        pthread_join(t[i], NULL);
    }

    return 0;
}
pthread_once(&rl_once, create_key)
不管多少个线程只有第一个执行它的线程运行一次被掉函数,保证了分配的rl_key的安全。

if ( (ptr = pthread_getspecific(rl_key)) == NULL) {// 检查当前线程key域是否有值

检查当前线程的pthread结构的key域是否有值

pthread_setspecific(rl_key, ptr);// 设置key的值
设置当前线程的pthread结构的key域的值

void destructor(void *value) {
    printf("pthread:%d destructor value(%p)\n", pthread_self(), value);
    free(value);// 线程结束后执行
}
线程结束后,会自动掉此析构函数,释放分配资源。

上例运行结果如下:

pthread:1691465472 create_key 0
pthread:1691465472 key(0) value(0x7f2b5c0008c0)
pthread:1680975616 key(0) value(0x7f2b540008c0)
pthread:1659995904 key(0) value(0x7f2b440008c0)
pthread:1659995904 destructor value(0x7f2b440008c0)
pthread:1680975616 destructor value(0x7f2b540008c0)
pthread:1691465472 destructor value(0x7f2b5c0008c0)
pthread:1649506048 key(0) value(0x7f2b3c0008c0)
pthread:1649506048 destructor value(0x7f2b3c0008c0)
pthread:1670485760 key(0) value(0x7f2b4c0008c0)
pthread:1670485760 destructor value(0x7f2b4c0008c0)


线程特定数据

标签:pthread   线程特定数据   c   多线程   

原文地址:http://blog.csdn.net/huanzai2/article/details/41117215

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!