首页 > 解决方案 > 为什么我们应该通过 pthread_setspecific 将键绑定到内存块,而不是只保留指向该块的指针?

问题描述

像往常一样,我们使用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也不同。那么为什么我们必须将内存绑定到一个键上,而不是只保留指针呢?

标签: c++linuxmultithreadingoperating-systempthreads

解决方案


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

pthread_setspecific()/接口的优点pthread_getspecific()是它可以让您避免簿记 - 特别是,需要通过所有代码路径将该指针传递给特定于线程的存储,以防某些叶函数需要它非常繁重。

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


推荐阅读