原子访问与内存一致性:深入理解同步关系
在多线程编程中,确保程序的正确性和性能是一项极具挑战性的任务。为了实现这一目标,我们需要对线程间的同步关系有深入的理解。本文将详细探讨“happened before”关系、C 库调用中的同步机制、顺序一致性以及其他一致性模型。
“happened before”关系
在分析程序执行时,我们需要了解所有线程状态的部分信息,并知道如何将这些信息拼接起来,以形成对整个程序的连贯视图。“happened before”关系(用 F →E 表示)是由 Lamport 引入的一个重要概念,它描述了两个评估 E 和 F 之间的先后顺序。
这个关系包含两部分:
-同一线程内的顺序:如果 F 在 E 之前被排序(sequenced before),那么 F →E。例如,在输入线程中,对 command[0] 的赋值操作在 switch 语句之前被排序,因此 switch 语句的所有情况都会在赋值之后执行。
-线程间的同步:线程间事件的顺序由同步机制提供,主要有两种类型:原子操作和某些 C 库调用。原子对象可以用于同步两个线程,当一个线程写入一个值,另一个线程读取该值时,就会发生同步。
原子操作保证局部一致性,即原子对象 X 的修改集合按照与处理 X 的任何线程的 sequenced-before 关系一致的顺序执行,这个顺序称为 X 的修改顺序。
例如,在下面的代码示例中:
Thread B x = 31; x = 5; y = x; x = 0; _