可见的副作用序列

时间:2019-04-17 14:40:54

标签: c multithreading concurrency language-lawyer

我对plt.figure(1) t = np.arange(0.0, 2.0, 0.01) s = 1 + np.sin(2*np.pi*t) plt.plot(t, s) plt.show() plt.figure(2) s = 1 + np.sin(4*np.pi*t) plt.plot(t, s) plt.show() 中定义的副作用的可见序列概念的定义感到困惑:

  

对原子对象5.1.2.4(p22)的可见副作用序列,其中   关于M的值计算B的最大连续性   以M的修改顺序排列的副作用子序列,其中   对于M,第一个副作用是可见的,并且对于每个   随后产生的副作用,并不是B发生在它之前。

这是我目前对该概念的理解:

由于关于B的可见副作用应该是“ B之前发生的最接近的副作用”,因此我可以想象以下情况:

B

考虑到上述情况,我假设_Atomic int i = 10; void *increment(void *ignored){ i++; printf("%d\n", i); //<<----- B } void *decrement(void *ignored){ i--; printf("%d\n", i); } int main(void){ i = 100; //start two threads with increment and decrement correspondingly } B函数中的值计算,因此对于increment而言,可见的副作用序列为“ B”, i++”。由于i--在创建线程之前已被排序,因此它不属于针对i = 100的可见的副作用序列。

我的解释是真的吗?

1 个答案:

答案 0 :(得分:1)

C2x标准的working draft合并了C17(“错误修正”)标准中所做的更改。对此部分所做的更改的主要目的是在C ++和C之间对齐内存一致性模型,并删除DR406缺陷报告中所述的冗余。

如您所见,委员会竭尽全力试图阐明内存一致性模型并简化构成“数据竞赛”的内容。

棘手的是,C17错误修正中只有一项更改是“规范性的”,这意味着在C2x标准最终定稿之前,符合标准的实现无需考虑对本节所做的更改。

就您对当前标准的 existing 部分的解释而言,我不得不说这是有争议的。标准委员会承认当前版本中的混乱和模棱两可,您最好等待本节有机会在新的C2x标准下安顿下来,然后再对此担心太多。

  

16 如果A与B同步,则评估A在评估B之前发生线程间线程    依赖关系在B之前排序,或者对于某些评估X:

     
      
  • A与X同步,并且X在B之前排序,
  •   
  • A在X和X线程间发生在B之前进行排序,或者
  •   
  • 一个线程间发生在X之前,而X线程间发生在B之前。

         
         

    15)“带有依赖项”关系是“先后排序”关系的子集,并且类似地严格在线程内。
      16)“依赖关系之前排序”关系类似于“与...同步”关系,但是在   发布/获取的地点。

  •   
     

17 注7“线程间发生在...之前”关系描述了“在...之前进行排序”,“同步”的任意串联。   与”和“依序排序”关系,但有两个例外。第一个例外是串联是   不允许以“依序排序”结尾,后接“依序排序”。出现此限制的原因是   参与“之前依赖顺序”关系的消费操作仅提供关于   该消耗操作实际上带有依赖项的操作。此限制仅适用的原因   这种连接的结尾是,任何后续的释放操作都将为先前的操作提供所需的顺序   消耗操作。第二个例外是,不允许串联完全由“先后顺序”组成。   进行此限制的原因是:(1)允许暂时关闭“线程间发生”,以及(2)   下面定义的“之前”关系提供了完全由“先后顺序”组成的关系。

     

18 如果A在B或A线程间发生之前被排序,则评估A在评估B之前发生   实施应在B之前。实施应确保没有程序执行证明了   “发生之前”的关系。

     

19 注8否则,只有通过使用消耗操作,才能实现此循环。

     

20 关于对象M的关于M的值计算B的可见副作用A满足   条件:

     
      
  • A发生在B之前,并且
  •   
  • 没有其他副作用X到M,使得A发生在X之前,X发生在B之前。   由评估B确定的非原子标量物体M的值应为存储的值   可见的副作用A。
  •   
     

21 注9如果对非原子物体的副作用有明显了解,则说明存在数据竞争,并且   行为是不确定的。

     

22 注意10这表明对普通变量的操作没有明显的重新排序。如果没有,实际上是无法检测到的   数据竞争,但有必要确保此处定义的数据竞争并在原子使用上有适当的限制,   在简单的交错(顺序一致)执行中对应于数据竞争。

     

23 由评估B确定的原子对象M的值应为某个对象存储的值   会改变M的副作用A,而B不会在A之前发生。

     

24 注11:给定评估可能会产生价值的一组副作用也受其余规则的限制   描述,特别是下面的一致性要求。

     

25 如果修改原子对象M的操作A发生在修改M的操作B之前,   那么A在M的修改顺序中应早于B。

     

26 注12上述要求被称为“写-写一致性”。

     

27 如果原子对象M的值计算A发生在M的值计算B之前,而A   从对M的副作用X取其值,则B计算的值应为   由X存储的值或由对M的副作用Y存储的值,其中在修改中Y跟随X   M的顺序。

     

28 注13上面的要求被称为“读-读一致性”。

     

29 如果原子对象M的值计算A发生在对M的操作B之前,则A应该   从对M的副作用X中获取其值,其中X以M的修改顺序先于B。

     

30 注14上面的要求被称为“读写一致性”。

     

31 如果原子对象M上的副作用X发生在M的值计算B之前,则   评估B应从X或修改后X产生的副作用Y中获取其值   M的顺序。

     

32 注15上面的要求被称为“读写一致性”。

     

33 注16这有效地禁止了编译器对单个对象的原子操作重新排序,即使两个操作都是   “放松”的负载。这样,它可以使大多数硬件提供的“缓存一致性”保证可用于C   原子操作。

     

34 注17:加载原子对象所观察到的值取决于“之前发生”关系,而该关系又取决于   原子物体的载荷观察到的值。预期的读数是存在原子载荷的关联   进行修改后,他们会观察到,连同适当选择的修改顺序以及“之前发生的”关系   如上所述得出的结果,可以满足此处强加的约束条件。