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

时间:2017-11-09 03:03:08

标签: c++ memory

在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 s :: a和S s :: b而不考虑S s的同步?

2 个答案:

答案 0 :(得分:0)

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

  

存储器位置可以是标量类型的对象,也可以是相邻位域的最大序列   非零宽度。

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

此外,这似乎至少与相同草案中的第9.6.2节相关:

  

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

同样的措辞分别是2017年第4.44和12.2.4.2节中的n4659。

我没有看到n4296中OP的确切含义,但这是在1.7.3节中:

  

两个或多个执行线程(1.10)可以更新和访问单独的内存   地点没有相互干扰。

答案 1 :(得分:0)

  你能吗?

在某种程度上,是的。但是,如果您需要[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16], [17, 18, 19, 20]] 来尊重并访问不同的成员/位置,那么不需要。 (显而易见,你不能同时销毁另一个线程s。)

  

你应该吗?

在这种情况下几乎肯定不会。否则,你只是打破了一个封装,它应该通过摆弄细节来简化设计。

那就是说,原则很重要,有一个更实际的例子:
当你有一个对象集合时,不同的线程可以在不同的元素上运行而不会出现并发问题:提供的集合中的添加/删除/移动项目具有适当的线程安全性

注意

您可能需要注意机器架构,以确定未对齐的相邻内存位置的线程安全性。 (即使硬件保护您,也可能会产生性能损失。)