为什么我们应该通过 pthread_setspecific 将键绑定到内存块而不是只保留指向该块的指针?

why should we bind a key to a memory block by pthread_setspecific rather than just keep the pointer to that block?

像往常一样,我们使用 pthread_setspecific 将动态分配的块绑定到全局键。

void do_something()
{
    //get thread specific data
    int* glob_spec_var = pthread_getspecific(glob_var_key);
        *glob_spec_var += 1;
}

void* thread_func(void *arg)
{
    int *p = malloc(sizeof(int));
    *p = 1;
    pthread_setspecific(glob_var_key, p);
    do_something();
    pthread_setspecific(glob_var_key, NULL);
    free(p);
    pthread_exit(NULL);
}

但是,如果我将 thread_func 简化为:

void do_something(int* p)
{
    //get thread specific data
    int* glob_spec_var = p; //pthread_getspecific(glob_var_key);
        *glob_spec_var += 1;
}

void* thread_func(void *arg)
{
    int *p = malloc(sizeof(int));
    *p = 1;
    // pthread_setspecific(glob_var_key, p);
    do_something(p);
    // pthread_setspecific(glob_var_key, NULL);
    free(p);
    pthread_exit(NULL);
}

它将做与上一个版本完全相同的事情。每个线程中的指针 p 也不同。那么为什么我们必须将内存绑定到一个键上,而不是只保留指针?

您确实可以通过在线程启动函数中分配它来实现您自己的线程特定存储,然后将指向它的指针传递给每个线程函数,并在线程退出时释放它。

pthread_setspecific() / pthread_getspecific() 接口的优势在于它可以让您避免记账——特别是,需要通过您的所有代码路径以防某些叶函数需要它是非常繁琐的。

这也意味着库代码可以访问线程本地存储,而无需库用户在每次调用时进行设置并将其传递给库。