Yanyg - SAN Software Engineer

线程本地存储(TLS)

线程本地存储(TLS, Thread-local Storage)是一种声明全局变量/静态变量为线程 本地变量的实现方法(每个线程都有自己独立的实例)。

典型的一种使用场景是MemPool:

分配;

否则加锁后将一批对象放回到MemPool。

GCC使用关键词 __thread 声明局部变量。如下是一个例子,其中 value 是一个 TLS变量。

#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

pthread_key_t test_key1;
pthread_key_t test_key2;

__thread unsigned long value;

void destruct_test_key1(void *p)
{
    printf("<Func %s>: thread(%u) p=%p, value=%p/%lu\n",
           __FUNCTION__, pthread_self(), p, &value, value);
}

void destruct_test_key2(void *p)
{
    printf("<Func %s>: thread(%u) p=%p, value=%p/%lu\n",
           __FUNCTION__, pthread_self(), p, &value, value);
}

void* thread_func(void *arg)
{
    usleep((unsigned long)arg % 1000);
    printf("<Func %s>: thread(%u) arg(%lu)\n",
           __FUNCTION__, pthread_self(), (unsigned long)arg);
    if ((unsigned long)arg == 1)
    {
        pthread_setspecific(test_key1, &value);
        value = 1000;
    }
    if ((unsigned long)arg == 2)
    {
        pthread_setspecific(test_key2, &value);
        value = 2000;
    }
    return NULL;
}

int main(int argc, char *argv[])
{
    int ret;
    ret = pthread_key_create(&test_key1, &destruct_test_key1);
    assert(ret == 0);
    ret = pthread_key_create(&test_key1, &destruct_test_key2);
    assert(ret == 0);

    pthread_t tid;
    ret = pthread_create(&tid, NULL, &thread_func, (void*)(unsigned long)1);
    assert(ret == 0);
    ret = pthread_create(&tid, NULL, &thread_func, (void*)(unsigned long)2);
    assert(ret == 0);
    ret = pthread_create(&tid, NULL, &thread_func, (void*)(unsigned long)3);
    assert(ret == 0);

    usleep(10000);

    return 0;
}

编译 gcc -o tls tls.c -lpthread 执行结果:

[email protected]:~/test$ ./tls
<Func thread_func>: thread(3569612544) arg(3)
<Func thread_func>: thread(3578005248) arg(2)
<Func destruct_test_key1>: thread(3578005248) p=0x7f4fd54406f8, value=0x7f4fd54406f8/2000
<Func thread_func>: thread(3586397952) arg(1)
<Func destruct_test_key2>: thread(3586397952) p=0x7f4fd5c416f8, value=0x7f4fd5c416f8/1000

References

  1. https://en.wikipedia.org/wiki/Thread-local_storage