有人能提供详尽的解释吗?我正在深入研究并发编程并在尝试理解共识时遇到这些寄存器。
From Lamport's "On interprocess communication": ...如果两个连续读取重叠相同的写入无法获得新的旧值... ,则常规寄存器是原子的。
假设,首先是thread0.write(0)
- 没有重叠。基本上,可以说使用Lamports定义,thread1
可以先读取 1 ,然后再次 0 ,如果两个读取都是结果并与thread0.write(1)
重叠。但那怎么可能呢?
答案 0 :(得分:31)
对共享内存位置的读取和写入需要一段有限的时间,因此它们可能重叠,也可能完全不同。
e.g。
Thread 1: wwwww wwwww
Thread 2: rrrrr rrrrr
Thread 3: rrrrr rrrrr
线程2的第一次读取与线程1的第一次写入重叠,而第二次读取和第二次写入不重叠。在线程3中,两个读取都与第一次写入重叠。
安全寄存器只有在不与写入重叠的读取时才是安全的。如果读取不与任何写入重叠,则它必须读取最近写入所写的值。否则,它可能返回寄存器可能持有的任何值。因此,在线程2中,第二次读取必须返回第二次写入所写的值,但第一次读取可以返回任何有效值。
常规寄存器增加了额外的保证,即如果读取与写入重叠,则它将读取旧值或新值,但多次读取与写入重叠不必同意在其上,值可能看起来来回“闪烁”。这意味着来自同一线程的两次读取(例如上面的线程3中)与写入重叠可能会出现“乱序”:较早的读取返回新值,后者返回旧值。
原子寄存器可确保读取和写入似乎在单个时间点发生。在该点之前起作用的读者将全部读取旧值,并且在该点之后起作用的读者将全部读取新值。特别是,如果来自同一线程的两个读取与写入重叠,那么如果先前的读取返回新值,则后一个读取不能返回旧值。原子寄存器可线性化。
Maurice Herlihy和Nir Shavit的The Art of Multiprocessor Programming给出了一个很好的描述,以及示例和用例。