Advanced Programming in UNIX Environment Episode 63

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/myfather103/article/details/79983991

Thread-Specific Data

Thread-specific data, also known as thread-private data, is a mechanism for storing and finding data associated with a particular thread. The reason we call the data thread-specific, or thread-private, is that we’d like each thread to access its own separate copy of the data, without worrying about synchronizing access with other threads.

First, sometimes we need to maintain data on a per-thread basis.

The second reason for thread-private data is to provide a mechanism for adapting process-based interfaces to a multithreaded environment.

Before allocating thread-specific data, we need to create a key to associate with the data. The key will be used to gain access to the thread-specific data.

#include <pthread.h>

int pthread_key_create(pthread_key_t *keyp, void (*destroy)(void *));

We can break the association of a key with the thread-specific data values for all threads by calling pthread_key_delete.

#include <pthread.h>

int pthread_key_delete(pthread_key_t key);
#include <pthread.h>

pthread_once_t initflag=PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *initflag, void (*initfn)(void));

The initflag must be a nonlocal variable (i.e., global or static) and initialized to PTHREAD_ONCE_INIT.

Once a key is created, we can associate thread-specific data with the key by calling pthread_setspecific. We can obtain the address of the thread-specific data with pthread_getspecific.

#include <pthread.h>

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

#define MAXSTRINGSZ 4096

static pthread_key_t key;
static pthread_once_t init_done=PTHREAD_ONCE_INIT;
pthread_mutex_t env_mutex=PTHREAD_MUTEX_INIALIZER;

extern char **environ;

static void thread_init(void)
{
    pthread_key_create(&key, free);
}

char *getenv(const char *name)
{
    int i,len;
    char *envbuf;

    pthread_once(&init_done, thread_init);
    pthread_mutex_lock(&env_mutex);
    envbuf=(char*)pthread_getspecific(key);
    if(envbuf==NULL)
    {
        envbuf=malloc(MAXSTRINGSZ);
        if(envbuf==NULL)
        {
            pthread_mutex_unlock(&env_mutex);
            return NULL;
        }
        pthread_setpecific(key,envbuf);
    }
    len=strlen(name);
    for(i=0;environ[i]!=NULL;i++)
    {
        if((strncmp(name, environ[i],len)&&
            (envrion[i][len]=='='))
        {
            strncpy(envbuf, &environ[i][len+1],MAXSTRINGSZ)
            pthread_mutex_unlock(&env_mutex);
            return envbuf;
        }
    }
    pthread_mutex_unlock(&env_mutex);
    return NULL;
}

A thread-safe, compatible version of getenv

猜你喜欢

转载自blog.csdn.net/myfather103/article/details/79983991