我对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
的可见的副作用序列。
我的解释是真的吗?
答案 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:加载原子对象所观察到的值取决于“之前发生”关系,而该关系又取决于 原子物体的载荷观察到的值。预期的读数是存在原子载荷的关联 进行修改后,他们会观察到,连同适当选择的修改顺序以及“之前发生的”关系 如上所述得出的结果,可以满足此处强加的约束条件。