线程键

大家都知道,在多线程程序中,所有线程共享程序中的变量。现在有一全局变量,

所有线程都可以使用它,改变它的值。

而如果每个线程希望能单独拥有它,那么就需要使用线程存储了。表面上看起来这是一个全局变量,所有线程都可以使用它,

而它的值在每一个线程中又是单独存储的。这就是线程存储的意义。

 

下面说一下线程存储的具体用法。
1) 创建一个类型为 pthread_key_t 类型的变量。

2)调用 pthread_key_create() 来创建该变量。该函数有两个参数,第一个参数就是上面声明的 pthread_key_t 变量,

第二个参数是一个清理函数,用来在线程释放该线程存储的时候被调用。该函数指针可以设成 NULL ,这样系统将调用默认的清理函数。

3)当线程中需要存储特殊值的时候,可以调用 pthread_setspcific() 。该函数有两个参数,第一个为前面声明的 pthread_key_t 变量,

第二个为 void* 变量,这样你可以存储任何类型的值。

4) 如果需要取出所存储的值,调用 pthread_getspecific() 。该函数的参数为前面提到的 pthread_key_t 变量,该函数返回

void * 类型的值。


下面是前面提到的函数的原型:

int pthread_setspecific(pthread_key_t key, const void *value);

void *pthread_getspecific(pthread_key_t key);

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

下面是一个如何使用线程存储的例子:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

pthread_key_t   key;


/*
 * @brief   free private struct
 * @param[in]  arg    pointer of private struct    
 */
void destr(void *arg)
{
 int *p = (int *)arg;
 
 printf("*arg = %u\n", (unsigned int)*p);
 free(p);
}


void test(void)
{
 int *p = (int *)pthread_getspecific(key);
 
 printf("*p = %u\n", (unsigned int)*p);
}

/*
 * @brief   thread proc
 * @param[in]  arg    thread parameter
 * @return      
 */
 
void *thread(void *arg)
{
 int i;
 pthread_t id = pthread_self();
 int *p = (int *)malloc(sizeof(int));
 
 printf("id = %u\n", (int)id);
 *p = (int)id;
 pthread_setspecific(key, p);
 test();
 
 return (void *)0;
}

int main(void)
{
 pthread_t id;
 int i;
 int ret;
 int pthread_arg = 100;
 void *pthread_ret;
 
 pthread_key_create(&key, destr);
 
 ret = pthread_create(&id, NULL, thread, &pthread_arg);
 if (ret != 0)
 {
  printf ("Create pthread error!\n");
  exit (1);
 }
 
 ret = pthread_create(&id, NULL, thread, &pthread_arg);
 if (ret != 0)
 {
  printf ("Create pthread error!\n");
  exit (1);
 }
 
 sleep(5);
 pthread_join(id, &pthread_ret);
 printf("pthread_ret = %d\n", (int)pthread_ret);
 
 return (0);
}

 

发布了19 篇原创文章 · 获赞 8 · 访问量 1万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章