我正在学习 POSIX 线程,我来到了有关线程特定数据的部分。这本书使用文件描述符做了一个很好的例子。但是,我想自己做同样的例子,除了这次使用全局变量。但是,我在完全掌握这个概念时遇到了一些困难。
我想做的是:
- 创建一个全局整数
- 为全局 int 声明一个键
主要是:
- 将全局整数设置为一个值,例如。 10
- 在不进行任何清理的情况下为其创建 key
- 创建4个线程并发送给它们执行thread_func
- 检查值是否仍然是 10,因为线程只能看到它的一个副本
在 thread_func 中:
- 使用 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 时确实尝试查看每个线程的内存地址时,我看到了相同的内存地址。也许有人可以给我举一个例子,他们使用全局变量(而不是文件描述符)并且他们有特定于线程的用法,其中线程将其视为局部变量。
最佳答案
这不是答案,而是旁注:
如果您正在处理特定于 Linux 的代码,您可以使用 __thread
关键字。本质上,
static __thread int counter = 5;
为每个线程创建一个不同的 counter
变量,每当创建一个新线程时初始化为值 5。这样的代码在未来与 C11 兼容,因为 C11 使用 _Thread_local
关键字标准化了相同的语义。这比 POSIX 特定于线程的函数(具有特定于实现的限制,并且与 __thread
关键字相比非常麻烦)在所有使用 C 的体系结构上都要明智得多,除了那些已声明 C99 和后来是“standard non grata”(即 Microsoft)。
关于c - 如何使用 POSIX 线程在 C 语言中创建特定于线程的全局变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15100824/