“共享内存的原子快照则要求扫描与数组更新共同线性一致,返回扫描调用区间内某个位置的向量。它不记录在途消息,也不以任意因果一致切片为返回规格;同名的“快照”不能替代对这两种目标的区分。”
形式陈述 ​
固定 update_i(v) 只由 scan() 由任意参与进程调用,返回整个向量。目标是使这两类操作共同线性一致,并且wait-free。
采用单写多读atomic 寄存器数组 (seq, value, view):无界递增整数序号、当前值,以及一个长为 A[i] = (0, v_i^0, initialValues)。写者有私有计数器 seq_i = 0;本页把整个记录的一次读写算作一个基础操作,尚不计算记录的位宽与拷贝成本。
collect() 按固定顺序各读一次
scan():
initial = collect()
previous = initial
loop:
current = collect()
if current == previous:
return values(current)
if some j satisfies current[j].seq >= initial[j].seq + 2:
return current[j].view
previous = current
update_i(v):
s = scan()
seq_i = seq_i + 1
A[i].write((seq_i, v, s))
数组相等指逐槽记录相等;序号不回绕使“写过又写回相同值”仍可被识别。内部 scan 与外部扫描使用同一算法;本进程执行它期间不会同时更新自己的槽。更新先扫描,再把新值、序号和扫描结果作为一个完整记录发布。
直觉
两次相同收集是一张“中间有过稳定状态”的证据,但只靠等待稳定可能永远重试。算法让每个更新者先交出一份完整视图:若它快到足以反复干扰别人,扫描者就借用它已经算好的答案。这是帮助机制的一种形式,帮助发生在信息共享上,不必由某个 helper 替别人执行同一段代码。
关键不是任意旧视图都可用,而是要证明被借用视图的采集发生在本次扫描区间内。序号至少增加二,正是定位这段时间包含关系的证据。
例子与边界
一次 collect 可以读到从未存在的向量 ​
取三个进程:
被持续更新时怎样借用答案 ​
令 seq 字段,完整 collect 仍读取全部记录。
| 步骤 | 推理 | |
|---|---|---|
| 首次 collect | 序号 |
保存为 initial 与 previous。 |
(1, 10, (0,0,0)) |
内部扫描先取得初始值,然后发布值 |
|
| 第二次 collect | 序号 |
两次不等,增量仅一,还不能借用。 |
(2, 20, (0,10,0)) |
它先取得包含旧值 |
|
| 第三次 collect | 序号 |
达到初始序号加二,返回存储视图 |
最后返回的不是最新值向量
正确性与步数界 ​
若相邻两次 collect 相等,对每个槽,从第一次读该槽到第二次读该槽之间都没有发布:否则无界序号必变。所有这些区间共同覆盖“第一次 collect 结束到第二次 collect 开始”的间隙。因此该间隙内数组恰等于返回向量,可把扫描线性化在那里。
若某槽序号从初次观察的
终止计数使用本进程的槽不会变化这一前提。每次未返回的相邻比较,至少有一个其他槽发生序号变化;同一个槽相对初次观察累计变化两次,就会触发借用。因此至多有
只有相等检测而没有借用分支时,对手可在每次收集之间插入更新,让扫描永久失败。有限位宽序号若直接回绕,也会让记录变化被相等比较掩盖;有界寄存器快照需要额外构造。宽记录包含整份视图,因而基础操作数不是机器字操作数,更不是传输位数。
推论与应用
原子快照把逐槽原子性提升到整个向量的读接口,可为共享状态监测和其他并发算法提供一个共同观察点。但它只更新调用者自己的分量,并不提供任意多项同时修改的事务。
Chandy–Lamport 分布式快照记录因果一致的进程与通道状态,目标是消息传递执行中的一致切片;本页则要求扫描与更新有共同线性化,并返回扫描区间内的寄存器向量。二者都叫快照,规格与模型却需分别检验。
自测:在上表第二次 collect 后,让
参考资料
- James Aspnes, Notes on Theory of Distributed Systems, 2026-04-25 版,§20.2 “Snapshots using double collects with helping”,Algorithm 20.1,印刷页 193–196;本页采用相邻 collect 复用形式。
- Yehuda Afek, Hagit Attiya, Danny Dolev, Eli Gafni, Michael Merritt, and Nir Shavit, “Atomic Snapshots of Shared Memory”, Journal of the ACM 40(4), 1993, pp. 873–890,§3 与 Figure 3。原文使用 double collect 组织扫描,不能将它的循环次数直接视为本页单次 collect 的次数。