假设我在 C: 中有一个这样的数组
static volatile bool my_array[128] = {0};
最重要的是,我有 128 个线程,每个线程每当完成时都会写入一个不同索引
true
。
这会产生一些问题吗?在 x64 上写入单个字节对周围的字节没有影响,对吗?
我只是问,因为我不确定CPU/内存控制器/等是否总是读取8(或4)字节,然后写入它们。这会产生一些奇怪的竞争条件。
非常感谢
数组中没有两个元素存储在 C 标准定义的相同“内存位置”中,因此数组的单独元素的并发访问或修改不会相互干扰,如 C17 3.14 第 2 段所确认:
3.14
唯一需要注意的是一系列具有非零宽度的相邻位字段中不同位字段成员的并发更新,如 C17 3.14 的下一段所证实:
- 内存位置
标量类型的对象,或具有非零宽度的相邻位字段的最大序列
- 条目注释 1
:两个执行线程可以更新和访问单独的内存位置,而不会互相干扰 其他。
条目注释 2
(强调我的)。- :位字段和相邻的非位字段成员位于不同的内存位置。这同样适用于两个位字段,如果一个位字段在嵌套结构声明内声明而另一个未声明,或者如果两者由零长度位字段声明分隔,或者如果它们由非位分隔- 现场成员声明。 如果在同一结构中声明的所有成员也是(非零长度)位域,则同时更新同一结构中的两个非原子位域是不安全的,无论这些中间位域的大小恰好是多少.
C17 3.14 的下一段提供了一个示例:
- 示例
声明为的结构
struct { char a; int b:5, c:11,:0, d:8; struct { int ee:8; } e; }
包含四个单独的内存位置:成员
a
、位字段d
和e.ee
都是单独的内存位置,并且可以同时修改而不会互相干扰。位域b
和c
一起构成了第四个存储位置。位字段b
和c
不能同时修改,但例如b
和a
可以同时修改。