C ++内存模型char vs word,并发?来自 Stroustrup 的书

Posted

技术标签:

【中文标题】C ++内存模型char vs word,并发?来自 Stroustrup 的书【英文标题】:C++ memory model char vs word, concurrency? From Stroustrup book 【发布时间】:2020-08-08 15:37:50 【问题描述】:

Stroustrup 在C++ 4th Ed Page 1193 中给出了以下示例。我的问题是使用两个线程的并发程序,一个用于f(),另一个用于g(),Stroustrup 的声明是:

如果链接器在内存中的同一个字中分配 c 和 b 并且(像大多数现代硬件一样)",

变量cb 会发生什么情况?

在某些硬件上,我的理解是一个单词是 2 个字节,并且两个变量都包含在其中,一个线程可能会覆盖另一个线程的 char

Stroustrup 进一步指出:

如果没有定义明确且合理的内存模型,线程 1 可能 读取包含 b 和 c 的单词,更改 c,然后将单词写回 进入记忆。同时,线程 2 可以对 b 做同样的事情。 然后,无论哪个线程设法先读到这个词,无论哪个 管理最后将其结果写回内存的线程将 确定结果。我们可能会得到 10、01 或 11(但不是 00)。这 记忆模型将我们从这种混乱中解救出来;我们得到 11. 00 的原因 不可能发生的是 b 和 c 的初始化已经完成(通过 编译器或链接器)在任一线程启动之前。

我的困惑是,为了解决这个问题,C++ 链接器是否将 c 放在一个 2 字节内存地址中,而将 b 放在另一个?

// thread 1
char c = 0;
void f()

    c = 1;
    int x = c;


char b = 0;
void g()

    b = 1;
    int y = b;

【问题讨论】:

"因为一个单词是 2 个字节" 需要引用。 移除 x86 并使用 2 个字节作为示例大小 @NicolBolas——微软在他们的标准中这么说。一定是这样的。 @Scheff -- 我在开玩笑。 @Andy 术语 word 是在 Microsoft 在其操作系统/API 中赋予它特定含义之前使用的。因此,字长通常取决于硬件 - 也用作“机器字长” - 一次处理的数量。 Word (Wikipedia) 【参考方案1】:

Stroustrup 的观点是,C++ 实现需要在特定硬件上执行任何必要的操作,以使事情按照内存模型的要求工作。这可能取决于硬件的细节。特定的缓存体系结构可能允许从不同线程同时修改同一“字”中的两个值。如果特定的缓存架构不能做到这一点,那么实现的工作就是确保每个单独的 C++ 对象仍然按照内存模型正确运行。这可能需要插入填充,或执行特殊的写入操作或其他任何操作。

【讨论】:

谢谢,所以在这个有 2 个线程的示例中,可以假设链接器或其他一些底层逻辑会确保这两个变量在访问方面是互斥的? IE。防止并发线程的问题? @notaorb 生成代码的编译器部分是为特定的 CPU 和架构编写的。 (这通常被称为后端,并且有像 gcc 这样的具有多个后端的编译器。)代码发射编译器部分的作者必须关心 CPU/架构细节。我相信这是编译器的一部分,而不是(或不仅)链接器的一部分。仅供参考:Compiler Design

以上是关于C ++内存模型char vs word,并发?来自 Stroustrup 的书的主要内容,如果未能解决你的问题,请参考以下文章

Golang面向并发的内存模型

Golang面向并发的内存模型

java的内存模型

Java虚拟机:十Java内存模型

Golang百万级高并发实例

Java内存模型