【问题标题】:Is access to different elements in a C array thread safe?访问 C 数组线程中的不同元素是否安全?
【发布时间】:2020-11-15 10:09:04
【问题描述】:

如果我有以下 C 代码:

int my_global_arr[100];

或更一般地说,

some_type *my_global_arr = malloc(some_size * sizeof(some_type);

在多个线程中同时访问(读取和写入)不同元素是否安全?
例如,如果我有

void *my_thread(void *index){
    int idx = *((int *)(index));
    my_global_arr[idx] = idx;
    return NULL;
}

main()

int a = 1;
int b = 2;
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, my_thread, &a);
pthread_create(&thread2, NULL, my_thread, &b);

pthread_join(thread1, NULL);
pthread_join(thread2, NULL);

能保证两个线程不会互相干扰吗?

我的实验:
我尝试运行上面的“程序”,在 x86_64 CPU 上扩展到 1000 个线程,100000 次 使用 GCC 8.3.0,-std=c99,看起来它们不会相互干扰; 但是,我认为这样的实验不足以得出这样的访问是 在所有平台上都是线程安全的。

编辑 1
这个问题是关于访问不同的不同元素 线程,不同线程中的元素不一样;那是, 例如,thread-1 读取/写入 arr[1]thread-2 读取/写入arr[2]

【问题讨论】:

  • 如果你不修改与其他线程访问相同的元素,它是 100% 安全的
  • @P__J__ 不相信这适用于所有架构和所有类型。

标签: c multithreading thread-safety pthreads


【解决方案1】:

[已编辑]

在 C 中访问数组的不同元素是完全线程安全的。

【讨论】:

  • 这个答案本身似乎是完全正确的,但我相信我的问题是关于访问 different 索引的元素,如问题第 5 行所述。
  • 哦。我当时误读了这个问题。我将编辑我的回复:)
  • 我不相信在只允许多字节访问(例如一次 32 个字节)的架构上可以保证访问数组的相邻字节是安全的,因此需要读取、布尔操作然后写入访问小于 32 位的类型。
【解决方案2】:

访问不同的元素始终是 100% 安全的。

【讨论】:

    【解决方案3】:

    如果你能保证一次,每个元素只能被一个线程访问,那么它就是线程安全的。因为数组的每个元素都彼此不同(物理上),这意味着它们是独立的内存部分。

    【讨论】:

    • 在一般情况下,小于 int 的类型或不是 int 的精确倍数的压缩类型怎么办?根据系统架构,这些类型可能需要通过读/布尔操作/写序列来访问,例如。只允许 32 位读/写的系统上的字节数?
    • @MartinJames 我认为在您解释的那种情况下,不可能同时由两个线程访问。
    • 为什么不呢?线程 A 读取,通过布尔掩码等修改寄存器中的字节,被中断,线程 B 读取,修改相邻字节,通过掩码修改其字节,写入。稍后,线程 A 会覆盖线程 B 所做的更改:(
    猜你喜欢
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多