“独立动作的相邻次序可交换,许多全序 interleaving 因而代表同一个偏序执行。happens before保留因果与同步边,而不是强迫无关事件排序。”
形式陈述 ​
固定一次合法执行的事件集合 unlock 与随后成功的 lock 配对。具体模型可以只采用其中一部分,不能把未由规范声明的墙上时间或缓存传播自行加边。
令
Happens-before 关系
合法执行要求这些生成边无环,因此
才是偏序的非严格形式。对两个不同事件
则称它们在该模型的 happens-before 意义下并发。这个定义只说二者不可比较,不保证其内存效果可交换。
直觉
Happens-before 记录可证明的信息流。程序顺序让同一线程的前一步影响后一步,消息接收携带发送之前的知识,同步操作把一个线程先前的写入交给另一个线程。传递闭包再把这些局部证据串成跨线程、跨节点的因果链。
它不是物理时间轴。两个事件即使在测量上先后相隔很久,只要模型没有程序、通信或同步路径,仍可能不可比;反过来,某些语言允许编译器重排机器指令,却仍要求抽象执行保持规定的 happens-before。分析必须始终说明关系属于哪一层。
例子与边界
消息执行中,进程
故
共享内存中,线程 data = 42,再以 release 语义写 ready = true;线程 ready 写取得 true,便有
所以数据写 happens-before 数据读。若 acquire 读没有观察该 release 写,或 ready 只是普通变量,所需 synchronizes-with 边可能不存在;仅凭读到了数值 true 不能跨语言模型自行补边。
语言模型还可能规定单个原子位置的 modification order、Java 同步动作的 synchronization order,或所有顺序一致原子的某个总序。这些附加次序不等于 happens-before 本身;只有规范指定的边才参与生成
推论与应用
Lamport 时钟保证
数据竞争用模型特定的 happens-before 判断冲突普通访问是否未排序;不可比的只读访问却不会因此成为 race。偏序约简还要求动作独立与交换,不能仅从两个事件无因果路径就推出交换执行保持所有观察。
参考资料
- Leslie Lamport, “Time, Clocks, and the Ordering of Events in a Distributed System,” Communications of the ACM 21(7), 1978, pp. 558–565。
- Nancy A. Lynch, Distributed Algorithms, Morgan Kaufmann, 1996,§6.2。
- Hans-J. Boehm and Sarita V. Adve, “Foundations of the C++ Concurrency Memory Model,” PLDI 2008, pp. 68–78。