Cal*_*Cal 11 c linux multithreading posix pthreads
我正在学习POSIX线程,我已经开始讨论线程特定数据.本书使用文件描述符做了一个很好的例子.但是,我想自己做同样的例子,除了这次使用全局变量.但是,我在完全理解这个概念时遇到了一些困难.
我想做的是以下内容:
在主要:
在thread_func中:
在do_something
这是代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,当你调用pthread_getspecific时,每个线程应该有自己唯一的内存地址的内存地址 - 我在这里没有发现这种情况.我知道我没有正确地解决这个问题,当我在做特定操作时尝试查看每个线程的内存地址时,我看到了相同的内存地址.也许有人可以指出我使用全局变量(不是文件描述符)的示例,并且它们具有特定于线程的用法,其中线程将其视为局部变量.
Nom*_*mal 18
这不是答案,而是旁注:
如果您正在使用特定于Linux的代码,则可以使用该__thread关键字.实质上,
static __thread int counter = 5;
Run Code Online (Sandbox Code Playgroud)
counter为每个线程创建一个不同的变量,每当创建一个新线程时初始化为值5.这样的代码与C11是未来兼容的,因为C11使用_Thread_local关键字标准化了相同的语义.这比__thread使用C的所有架构上的POSIX线程专用函数(具有特定于实现的限制,并且与关键字相比非常麻烦)更加安全,除了那些已声明C99以及之后" 标准不受欢迎 "的架构(即,微软).
Who*_*aig 15
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", (unsigned int) pthread_self(), *glob_spec_var);
*glob_spec_var += 1;
printf("Thread %d after mod value is %d\n", (unsigned int) pthread_self(), *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,thread_func,NULL);
for (i=0; i < NUMTHREADS; i++)
pthread_join(threads[i], NULL);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产量
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
Run Code Online (Sandbox Code Playgroud)