C 内存模型是否提供了有关构造函数操作的保证

Does the C++ memory model provide guarantees about the operations of constructors

本文关键字:构造函数 操作 模型 内存 是否      更新时间:2023-10-16

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

当您有多个线程共享对对象的访问并修改对象的访问时,可能会有种族危害。可以通过安全地发布所有线程的对象(包括所有可能的未来线程),因此可以避免这些问题。随后对物体的访问将无需使用锁(静音)即可免于种族危害。在极端情况下,对象是不可变的:一旦构造,就永远不会更改。因此,在多线程程序中使用不变的对象有一个习惯。

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

在编程高级便携式编程语言(例如C )时,您不会关注缓存和缓存潮红的详细信息。相反,该语言提供了一组保证(内存模型),您必须根据某些成语编写代码以可靠地实现您的目标。

在Java中,这是自动通过遵循类设计中的某些规则(进行简化:制作所有final),这有点像C 中的const),Java内存模型保证将导致所需效果。这可以通过在执行构造函数的代码后立即具有内存屏障来实现。

在C 11中如何完成?C 内存模型是否提供有关构造函数的操作的保证,这使您能够自动发布新构造的对象?如果是这样,您的课程规则是什么?如果没有,您必须自己添加一个内存障碍(显然您必须为.NET做的)

或C 11不提供对不变对象的无线安全访问?您是否必须使用静音的所有访问共享对象(是否不可变)?

有两个主要情况:

  1. 读取线程的创建是订购的 - 在创建对象之后
  2. 读取线程的创建是不是订购的 - 在创建对象之后

在情况1中,读取对对象的访问会自动安全,因为在线程中订购的读取 - 在创建线程本身之后。

在情况2中,您必须以某种方式订购读取,这正是因为线程创建没有提供订单。很明显,如果未订购读取 - 在对象的创建后,事情就会出错。

您的问题想知道CPU缓存等细节。这是编译器作家的关注点。您只需要遵守C 订购规则。