从不可靠对象到可靠对象:原子寄存器与共识问题解析
1. 引言
在并发编程领域,并发对象是可以被多个进程同时访问的对象。这类对象由接口和规范来定义,规范可以是顺序的,也可以是非顺序的。例如,并发队列就具有顺序规范,而故障检测器则没有。顺序规范意味着在某个抽象层面上,对象的行为可以描述为每个操作瞬间执行且无并发。常见的具有顺序规范的并发对象包括共享队列(在教科书中通常以生产者/消费者问题来描述其实现)和共享文件(也称为磁盘或寄存器,其实现是读者/写者问题的基础)。
当访问并发对象的操作重叠时,传统的做法是使用锁来确保对象的顺序规范不被违反。然而,在异步系统中,基于锁的方法存在严重的缺点。如果一个慢进程长时间持有锁,会延迟其他更快进程对对象的访问。更严重的是,基于锁的方法本身无法防止死锁的发生,而防止死锁需要额外的机制或策略,这可能导致长时间的等待,降低整个系统的效率。在出现故障的情况下,问题会变得更加严重。当持有锁的进程崩溃时,由于系统是异步的,无法确定该进程是崩溃了还是只是运行缓慢,这可能会导致系统被阻塞任意长的时间。
为了解决这些问题,出现了无等待对象实现的概念。无等待意味着每个执行对象操作的进程都可以在不等待其他进程的情况下继续执行,无论其他进程的当前状态和行为如何。Maurice Herlihy 证明了,任何具有顺序规范的并发对象都可以通过可靠的原子寄存器(共享变量)和共识对象实现无等待。这个结果被称为共识的通用性。通用构造是一种无等待算法,它根据任何顺序类型 T 的规范,从原子寄存器和共识对象构建类型 T 的并发对象。
2. 计算模型
2.1 进程、寄存器和共识对象
- 进程模型