我正在学习POSIX线程,我来到了线程特定数据部分.这本书是使用文件描述符的一个很好的例子.但是,我想自己做同样的例子,除了这个时候使用一个全局变量.但是,我很难把握这个概念.
我想做的是以下几点:
>创建一个全局整数
>为全局int声明一个键
主要内容:
>将全局整数设置为值例如. 10
>创建一个钥匙,没有任何清理
>创建4个线程并发送它们来执行thread_func
>检查值是否仍然为10,因为线程只能看到它的副本
在thread_func中:
>使用pthread_setspecific(键,全局变量)创建一个本地实例 – 不知道我是否正确地解释
>调用函数 – dosomething()
>退出
在do_something
>创建一个本地指针并将其分配给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",*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时,每个线程应该有内存地址的唯一内存地址 – 我没有找到这种情况.我知道我不会正确地做这个事情,当我尝试看具体的每个线程的内存地址时,我看到了相同的内存地址.有人可能会指出一个例子,他们使用全局变量(而不是文件描述符),并且它们具有线程特定的使用,线程将其视为局部变量.
解决方法
TLS(线程本地存储)的目的是提供一种定义的机制,其中代码可以检索存储在由所有线程已知共享密钥访问的数据库中的线程特定数据.您的代码在TLS中存储相同的数据:单个全局变量的地址).因此,当一个线程使用tls-key来请求这些数据时,他们都将返回相同的地址.
我想你打算你的代码做这样的事情:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #define NUMTHREADS 4 pthread_key_t glob_var_key; void do_something() { //get thread specific data int* glob_spec_var = pthread_getspecific(glob_var_key); printf("Thread %d before mod value is %d\n",*glob_spec_var); *glob_spec_var += 1; printf("Thread %d after mod value is %d\n",*glob_spec_var); } void* thread_func(void *arg) { int *p = malloc(sizeof(int)); *p = 1; pthread_setspecific(glob_var_key,p); do_something(); do_something(); pthread_setspecific(glob_var_key,NULL); free(p); pthread_exit(NULL); } int main(void) { pthread_t threads[NUMTHREADS]; int i; pthread_key_create(&glob_var_key,NULL); for (i=0; i < NUMTHREADS; i++) pthread_create(threads+i,NULL); for (i=0; i < NUMTHREADS; i++) pthread_join(threads[i],NULL); return 0; }
产量
Thread 2625536 before mod value is 1 Thread 741376 before mod value is 1 Thread 3162112 before mod value is 1 Thread 3698688 before mod value is 1 Thread 2625536 after mod value is 2 Thread 741376 after mod value is 2 Thread 3162112 after mod value is 2 Thread 3698688 after mod value is 2 Thread 2625536 before mod value is 2 Thread 741376 before mod value is 2 Thread 3162112 before mod value is 2 Thread 3698688 before mod value is 2 Thread 2625536 after mod value is 3 Thread 741376 after mod value is 3 Thread 3162112 after mod value is 3 Thread 3698688 after mod value is 3