假设我在C中有一个这样的数组:

static volatile bool my_array[128] = {0};

最重要的是,我有128个线程,每个线程在完成时都会写入different索引true.

这会产生一些问题吗?写一个字节对x64上的周围字节没有影响,对吗?

我只是问问,因为我不确定CPU /内存控制器/等是否总是读取8(或4)字节,然后写入它们.这会产生一些奇怪的竞争条件.

非常感谢

推荐答案

正如C17 3.14第2段所确认的,数组中没有两个元素存储在C标准定义的相同的memory location中,因此对数组中单独元素的并发访问或修改不会相互干扰:

3.14

  1. memory location

    标量类型的对象或具有非零宽度的相邻位域的最大序列

  2. Note 1 to entry:两个执行线程可以更新和访问单独的内存位置,而不会相互干扰 其他的.

唯一需要注意的是,在一系列具有非零宽度的相邻位域中,不同位域成员的并发更新,如C17 3.14的下一段所确认的:

  1. Note 2 to entry:位域和相邻的非位域成员位于不同的存储位置.这同样适用于两个位字段,如果一个在嵌套 struct 声明中声明,而另一个没有声明,或者如果这两个位字段由零长度的位字段声明分隔,或者如果它们由非位字段成员声明分隔.It is not safe to concurrently update two non-atomic bit-fields in the same structure if all members declared between them are also (nonzero-length) bit-fields, no matter what the sizes of those intervening bit-fields happen to be.

(强调我的).

C17 3.14的下一段提供了一个例子:

  1. EXAMPLE一个 struct 声明为

    struct {
          char a;
          int b:5, c:11,:0, d:8;
          struct { int ee:8; } e;
    }
    

    包含四个单独的存储位置:成员100和位域101102都是单独的存储位置,并且可以同时修改而不相互干扰.位字段103104一起构成第四存储位置.位字段103104不能被同时修改,但是例如103100可以被修改.


NOTE

我推测对"压缩"数组的不同元素或对压缩 struct 的不同成员的并发访问在某些体系 struct 上可能是不安全的,但这超出了C规范的范围.

C++相关问答推荐

Tiva TM4C123GXL的I2C通信

DPDK-DumpCap不捕获端口上的传入数据包

将指针作为参数传递给函数

仅在给定的大小和对齐方式下正确创建全局

为什么GCC C23中的关键字FALSE不是整数常量表达式?

X64:并发写入布尔数组

使用TCL C API导航到列表中的元素

正数之和是负数

为什么realloc函数在此代码中修改变量?

C语言中MPI发送接收字符串时出现的分段错误

不带Malloc的链表

哪个首选包含第三个库S头文件?#INCLUDE;文件名或#INCLUDE<;文件名&>?

赋值两侧的后置增量,字符指针

将复合文字数组用作临时字符串缓冲区是否合理?

程序对大输入给出错误答案

强制GCC始终加载常量(即只读),即使启用了优化

区分MySQL C界面中的文本和BLOB字段

如果类型是新的,offsetof是否与typeof一起工作?

在C中使用字符串时是否不需要内存分配?

为什么 C 字符串并不总是等同于字符数组?