c - 如何使用 POSIX 线程在 C 语言中创建特定于线程的全局变量?

标签 c linux multithreading pthreads posix

我正在学习 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)。

参见 Thread-Local Storage chapterGCC documentation了解详情。

关于c - 如何使用 POSIX 线程在 C 语言中创建特定于线程的全局变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15100824/

相关文章:

c# - 如何从 C# 线程获取成员函数作为该线程参数的对象?

java - future.isDone 即使任务完成也会返回 false

c - C、Linux 中的图形编程

c - 判断 FILE * 是否可写

c - 这两种说法有什么区别?

linux - 如何使用 sed 删除 HH :MM:SS. [sss] 的毫秒部分?

Linux for armv8 - 避免所有空闲处理器状态

Linux Redhat 通过可执行文件执行命令

java - java中同时启动2个线程

c - execvp 不会打印 echo 命令