C 内存模型是否提供了有关构造函数操作的保证
Does the C++ memory model provide guarantees about the operations of constructors
您如何确保新构建的不变对象可以在C 中的线程中安全共享?C 内存模型是否提供有关构造函数的操作的保证?
当您有多个线程共享对对象的访问并修改对象的访问时,可能会有种族危害。可以通过安全地发布所有线程的对象(包括所有可能的未来线程),因此可以避免这些问题。随后对物体的访问将无需使用锁(静音)即可免于种族危害。在极端情况下,对象是不可变的:一旦构造,就永远不会更改。因此,在多线程程序中使用不变的对象有一个习惯。
仍然需要在构造函数中执行代码后安全发布对象。构造函数执行的代码将值分配给内存位置,但是这些书面值可能(最初)仅存在于CPU的本地缓存中。访问这些内存位置的其他线程可能会看到在这些内存位置记录的旧值(例如,malloc
设置的0x00字节模式)。对于新建的对象所涵盖的内存位置,必须有一种机制来冲洗本地缓存并使其他CPU的缓存无效。
在编程高级便携式编程语言(例如C )时,您不会关注缓存和缓存潮红的详细信息。相反,该语言提供了一组保证(内存模型),您必须根据某些成语编写代码以可靠地实现您的目标。
在Java中,这是自动通过遵循类设计中的某些规则(进行简化:制作所有final
),这有点像C 中的const
),Java内存模型保证将导致所需效果。这可以通过在执行构造函数的代码后立即具有内存屏障来实现。
在C 11中如何完成?C 内存模型是否提供有关构造函数的操作的保证,这使您能够自动发布新构造的对象?如果是这样,您的课程规则是什么?如果没有,您必须自己添加一个内存障碍(显然您必须为.NET做的)
或C 11不提供对不变对象的无线安全访问?您是否必须使用静音的所有访问共享对象(是否不可变)?
有两个主要情况:
- 读取线程的创建是订购的 - 在创建对象之后
- 读取线程的创建是不是订购的 - 在创建对象之后
在情况1中,读取对对象的访问会自动安全,因为在线程中订购的读取 - 在创建线程本身之后。
在情况2中,您必须以某种方式订购读取,这正是因为线程创建没有提供订单。很明显,如果未订购读取 - 在对象的创建后,事情就会出错。
您的问题想知道CPU缓存等细节。这是编译器作家的关注点。您只需要遵守C 订购规则。
- 避免通过操作从私有构造函数间接实例化
- 如果普通默认构造函数不执行任何操作,为什么我们不能使用 malloc 创建平凡可构造的对象?
- 复制构造函数、按值传递和按值返回、链式操作、编译器
- 更改操作的构造函数顺序
- 如果默认构造函数不执行任何操作,则目的是什么
- 为什么为单个赋值操作调用复制构造函数和重载赋值运算符
- C 内存模型是否提供了有关构造函数操作的保证
- 如何编写两个初始化操作(一个作为默认初始化,另一个作为用户输入)?两者都是类的构造函数C++
- 不执行任何操作的结构的构造函数
- std::vector 的复制构造函数是如何操作的?
- 在语法构造函数中评估的语义操作(或不评估?
- 构造函数中对整数数组的memcpy()操作在C++中给出了意外的输出
- 当我修改复制构造函数以执行一些奇怪的操作,然后按值将对象(该类)传递给函数时会发生什么
- 语句调用构造函数,但对构造函数不做任何操作——为什么它不能编译
- 构造函数初始化列表vs昂贵操作
- 删除复制构造函数/赋值会破坏标准库操作吗?
- 赋值操作和对象传递期间的构造函数调用
- 2好友构造函数的操作
- 标准函数和操作在类构造函数中不起作用
- 对内存分配和构造函数的调用是否可以与执行"new"表达式所需的其他操作交错?