不同的线程同时访问不同的内存位置

Different threads access different memory locations concurrently

本文关键字:位置 内存 线程 访问      更新时间:2023-10-16

在C++14中,有一个句子类似于:

Different threads of execution are always allowed to access (read and modify) different memory locations concurrently, with no interference and no synchronization requirements.
struct S {
char a;     // memory location #1
int b : 5;  // memory location #2
int c : 11, // memory location #2 (continued)
: 0,
d : 8;  // memory location #3
struct {
int ee : 8; // memory location #4
} e;
} obj; // The object 'obj' consists of 4 separate memory locations

这意味着我们可以使用两个线程来更改S::a和S::b,而无需考虑S的同步?

至少从2014年的n4296开始,第1.7.3节:

内存位置要么是标量类型的对象,要么是相邻位字段的最大序列,所有位字段都具有非零宽度。

所以,是的,你的直觉似乎是正确的,你可以在不同步的情况下从单独的线程读取和写入它们。

此外,这似乎至少与同一草案中的第9.6.2节有切点关系:

作为一种特殊情况,宽度为零的未命名位字段指定在分配单元边界处的下一个比特字段的对齐

2017年的n4659中,第4.4.3节和第12.2.4.2节分别使用了相同的措辞。

我看不出n4296中OP的确切措辞,但这在第1.7.3节:中

两个或多个执行线程(1.10)可以更新和访问单独的内存位置而不会相互干扰。

你能吗?

在某种程度上,是的。然而,如果你需要s来尊重和访问不同的成员/位置,那么不需要。(很明显,你不能让另一个线程同时破坏s。)

应该吗?

在这种情况下,几乎可以肯定不是。否则,您只是简单地分解了一个封装,该封装本应通过篡改细节来简化设计。

也就是说,这一原则很重要,有一个更实用的例子:
当你有一个对象集合时,不同的线程可以在不同的元素上操作,而不考虑并发性:只要在集合中添加/删除/移动项目具有适当的线程安全性

谨慎

您可能需要注意机器体系结构,以确保未对齐的相邻内存位置的线程安全。(即使硬件保护你,这也可能会付出性能成本。)