Linux/UNIX学习之线程特有数据

要使用线程特有数据,库函数执行的一般步骤如下:

(1)、函数创建一个键(Key),用以将不同函数使用的线程特有数据项区分开来。

(2)、函数会为每个调用者线程创建线程特有数据块。

(3)、为了保存上一步所分配存储块的地址,函数会使用pthread_setspecific()和pthread_getspecific()。

下面将详细介绍以上步骤中所使用到的函数:

(一)、调用pthread_key_create()函数为线程特有数据创建一个新键,并通过key所指向的缓冲区返回调用者。只要线程终止时与key的关联值部位NULL,Pthread API会自动执行解构函数,并将与key的关联值作为参数传入解构函数中。

#include <pthread.h>
int pthread_key_create(pthread_key_t *key,void(*destructor)(void*));

                         Return 0 on success,or a positive error number on error.

参数key:因为进程中的所有线程都可以使用返回的键,所以该参数应该指向一个全局变量;

参数destructor:指向一个自定义函数,一般格式如下:

void destructor(void *value)
{
    /*Release storage pointed to by 'value'*/
}

(二)、函数pthread_setspecific()和pthread_getspecific()。函数pthread_setspecific()要求Pthread API将value的副本存储到一数据结构中,并将value与调用线程以及key相关联。而pthread_getdpecific()函数的操作步骤与此相反。函数原型如下:

#include <pthread.h>
int pthread_setspecific(pthread_key_t key, const void *value);

                        Return 0 on success,or a positive error number on error;
int pthread_getspecific(pthread_key_t key)

                 Return Pointer,or NULL if no thread-specific data isassociated with key 

函数pthread_setspecific()的参数value通常是一个指针,指向由调用者分配的一块内存。当线程终止时,会将该指针作为参数传递给与key对应的解构函数中。

例程程序如下:

#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <tlpi_hdr.h>

static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t strerrorkey;

#define MAX_ERROR_LEN 256

static void destructor(void *buf)
{
   free(buf);
}


static void creatkey(void)
{
    int s;
    s = pthread_key_create(&strerrorkey,destructor);
    if(s!=0)
        errExitEN(s,"pthread_key_create");
}

char * strerror( int err)
{
    int s;
    char *buf;
    s = pthread_once(&once,createkey);
    if(s!=0)
        errExitEN(s,"pthread_once");
    buf = pthread_getspecific(strerrorkey)
    if(buf == NULL)
        {
            buf = malloc(MAX_ERROR_LEN);
            if(buf == NULL)
                errExit("malloc");
            s = pthread_setspecific(strerrorkey,buf);
            if(s!=0)
                errExitEN(s,"pthread_setspecific");
        }
    if(err<0||err>= _sys_nerr || _sys_errlist[err] == NULL)
        {
            snprintf(buf,MAX_ERROR_LEN,"Unknown error %d",err);
        }
    return buf;


}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值