gpt4 book ai didi

java - C++ 内存模型是否提供关于构造函数操作的保证

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:42:11 24 4
gpt4 key购买 nike

关闭。这个问题需要更多 focused .它目前不接受答案。












想改进这个问题?更新问题,使其仅关注一个问题 editing this post .

4年前关闭。




Improve this question




您如何确保新构造的不可变对象(immutable对象)在 C++ 中的线程之间安全共享? C++ 内存模型是否提供有关构造函数操作的保证?

当您有多个线程共享对一个对象的访问权并且该对象被修改时,可能存在竞争风险。可以通过将对象安全地发布到所有线程(包括所有可能的 future 线程)来避免这些问题,因此从任何线程对对象的所有后续访问都会看到相同的对象状态,然后避免修改对象。在不使用锁(互斥锁)的情况下,对对象的后续访问将不受竞争危害的影响。在极端情况下,对象是 immutable : 一旦构建,它就永远不会改变。因此,在多线程程序中尽可能多地使用不可变对象(immutable对象)是一种习惯用法。

这仍然需要在构造函数中的代码执行后安全地发布对象。构造函数执行的代码将值分配给内存位置,但那些写入的值可能(最初)仅存在于 CPU 的本地缓存中。访问这些内存位置的其他线程可能会看到记录在这些内存位置的旧值(例如由 malloc 设置的 0x00 字节模式)。对于新构建的对象所覆盖的内存位置,必须有一种机制来刷新本地缓存并使其他 CPU 的缓存无效。

在编写高级可移植编程语​​言(如 C++)时,您不必关心缓存和缓存刷新的细节。相反,该语言提供了一组保证(内存模型),您必须根据一些习惯用法编写代码才能可靠地实现您的目标。

在 Java 中,这是 自动通过遵循类设计中的一些规则来完成(过度简化: make everything final ,即 somewhat like const in C++ ),Java 内存模型保证会产生预期的效果。这可以通过在执行构造函数的代码后立即设置内存屏障来实现。

这是如何在 C++11 中完成的? C++ 内存模型是否为构造函数的操作提供保证,使您能够自动发布新构造的对象?如果是这样,你的类(class)有什么规则?如果没有,并且您必须自己添加内存屏障(如 you apparently have to do for .Net ),是否有一个习惯用法可以在构造后有效地发布对象?

还是 C++11 不提供对不可变对象(immutable对象)的线程安全无锁访问?您必须使用互斥锁保护对共享对象(不可变或不可变)的所有访问吗?

最佳答案

主要有两种情况:

  • 读取线程的创建是有序的——在对象创建后
  • 阅读线程的创建是不是 在创建对象后排序

  • 在情况 1 中,对对象的读取访问自动是安全的,因为线程中的读取是在线程本身创建之后排序的。

    在情况 2 中,您必须以某种方式订购读取,这正是因为线程创建不提供顺序。很明显,如果在创建对象之后没有对读取进行排序,那么事情就会出错。

    您的问题想知道 CPU 缓存等细节。这是编译器编写者关心的问题。您只需要遵守 C++ 排序规则。

    关于java - C++ 内存模型是否提供关于构造函数操作的保证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47459833/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com