【发布时间】:2013-02-12 14:16:50
【问题描述】:
我正在学习 POSIX 线程,我已经来到线程特定数据部分。这本书使用文件描述符做了一个很好的例子。但是,我想自己做同样的例子,除了这次使用全局变量。但是,我很难完全掌握这个概念。
我想做的是:
- 创建一个全局整数
- 为全局 int 声明一个键
主要:
- 将全局整数设置为一个值,例如。 10
- 无需任何清理即可为其创建密钥
- 创建4个线程并发送给执行thread_func
- 检查值是否仍为 10,因为线程只看到它的副本
在线程函数中:
- 使用 pthread_setspecific(key,global variable) 创建一个本地实例 - 不确定我是否正确解释了这个
- 调用函数 - dosomething()
- 退出
在做某事
- 创建一个本地指针并将其分配给 pthread_getspecific(key) - 这应该让我获得全局变量的线程特定版本
- 将本地指针中存储的值更改为 2
- 退出
代码如下:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUMTHREADS 4
pthread_key_t glob_var_key;
int glob_var;
void do_something()
{
//get thread specific data
int* glob_spec_var = (int*) pthread_getspecific(glob_var_key);
printf("Thread %d glob_spec before mod value is %d\n", (unsigned int) pthread_self(), *glob_spec_var);
*glob_spec_var = 2;
printf("Thread %d glob_spec after mod value is %d\n", (unsigned int) pthread_self(), *glob_spec_var);
}
void* thread_func(void *arg)
{
pthread_setspecific(glob_var_key, &glob_var);
do_something();
pthread_exit(NULL);
}
int main(void)
{
pthread_t threads[NUMTHREADS];
int i;
glob_var = 10;
pthread_key_create(&glob_var_key,NULL);
printf("Main: glob_var is %d\n", glob_var);
for (i=0; i < NUMTHREADS; i++)
{
pthread_create(&threads[i],NULL,thread_func,NULL);
}
for (i=0; i < NUMTHREADS; i++)
{
pthread_join(threads[i], NULL);
}
printf("Main: glob_var is %d\n", glob_var);
return 0;
}
据我了解,当您调用 pthread_getspecific 时,每个线程都应该有自己唯一的内存地址作为内存地址——我在这里没有发现这种情况。我知道我没有正确处理这个问题,当我在执行 getspecific 时尝试查看每个线程的内存地址时,我看到了相同的内存地址。也许有人可以给我举个例子,他们使用全局变量(而不是文件描述符)并且他们具有线程特定的用法,其中线程将其视为局部变量。
【问题讨论】:
-
您不应该在每个线程键中设置 same 地址。每个线程在线程启动期间将它们的唯一数据设置为公共键。有关其他示例,请参阅this example。当
do_something()被触发时,它将在指定键处获取当前线程特定的数据。这允许通用代码对当前线程的数据进行操作,而不是自己在一些线程到数据的映射中维护它。 -
感谢您的示例。我只是想找到一个使用全局变量但线程可以在本地修改它的体面示例,并且这些更改只能由该线程看到。这只是为了练习。请您详细说明地址部分,如果不是太麻烦,请告诉我正确的方法?
-
您是否希望在正确设置后,每个线程都将其 自己的 变量存储在 thread-local-storage (TLS) 中?这个问题的答案对于了解准确你的最终目标是至关重要的。如果您希望所有线程共享 same 全局,则需要使用互斥锁或临界区。那么你可以详细说明一下吗=P?
-
哦,我太傻了。我明白我做错了什么——这个例子非常好。我完全误解了这一点。他们 malloc 为每个线程函数的结构,然后 setspecific - 然后调用下一个函数,以便该函数将看到与该线程有关的数据,并且看起来像每个线程的本地副本。我的推理是否正确?
-
"您是否希望在正确设置后,每个线程都有自己的变量存储在线程本地存储 (TLS) 中?答案对于准确了解您的最终目标至关重要是。如果你希望所有线程共享同一个全局,那么互斥锁或临界区是有序的。所以你能详细说明一下 =P 吗? - WhozCraig 3 分钟前“我最初的想法是我创建了一个全局变量,并且 getspecific 和 setspecific 会为每个线程创建该变量的本地副本 - 我不认为会发生这种情况。
标签: c linux multithreading pthreads posix