c++ - 为什么我们应该通过 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
也不同。那么为什么我们必须将内存绑定到一个键上,而不是只保留指针呢?
解决方案
您确实可以通过在线程启动函数中分配它来实现自己的线程特定存储,然后将指向它的指针传递给每个线程函数,并在线程退出时释放它。
pthread_setspecific()
/接口的优点pthread_getspecific()
是它可以让您避免簿记 - 特别是,需要通过所有代码路径将该指针传递给特定于线程的存储,以防某些叶函数需要它非常繁重。
这也意味着库代码可以访问线程本地存储,而无需库用户在每次调用时对其进行设置并将其传递给库。
推荐阅读
- c# - 在检查它是否是子对象而不是父对象之后,如何使用特定子对象的参数/函数?
- php - PHP 是否允许在其他函数/方法中调用 getter?
- javascript - 如何从 JSON 中获取索引并将它们放入 HTML 表中?
- ios - 更改为横向时如何使文本与文本视图顶部对齐
- javascript - 在脚本加载之前停止随机元素显示的标准方法是什么?
- java - 如何对两个对象数组列表进行排序?
- java - 显示窗口后的Java OpenGL,出现无响应
- python - 运行时设置为 python37 时 dev_appserver.py 无法运行
- c# - 如何将此查询转换为不等于版本
- python - 不断收到 AttributeError: 'list' object has no attribute 'split' 错误