Answers:
为了确保我们在同一页面上,首先让我们考虑以下三个定义:
定义。测试设置是一些二进制寄存器(让我们说0和1是可能的值)上的读-修改-写指令,其中线程获得旧值并写入1。
定义。如果所有线程都决定同一个值(一致性要求),并且所有线程都决定由其中一个线程实际提出的值(有效性要求),则在线程之间达成共识。
定义。如果每个方法调用均以有限的步骤完成,则共识协议无需等待。
现在遵循两个证明草图。
声明1.测试集的共识数量至少为2. 证明。假设我们有两个线程0和1需要达成共识。我们可以通过让每个线程遵循以下共识协议来做到这一点:
您可以验证自己是否满足共识和等待时间。
(对于下一个证明,我将嵌套一些证明和定义,因为我认为这将使其更容易理解。)
声明2.测试集的共识数最多为2. 证明。通过矛盾。假设我们有三个线程,和希望分别决定值,和,并且我们有一些有效的免等待共识协议,该协议使用测试和设置(以及原子读写)实现)。
我们可以将共识过程可视化为有向树,其中:
定义。如果尚未确定共识过程的结果,则使状态为多价。换句话说,并非所有可能的其余移动交错都导致相同的结果。让我们的状态是单价时的共识进程的结果是确定的。
根是多价的。 证明。如果只有一个线程处于活动状态,而其他线程永远处于休眠状态,则将以有限数量的步长完成(由等待自由假设保证),并且它将决定(因为它只能访问该值及其值决定将满足共识有效性要求)。因此,对于我们的情况,,和都是可能的结果。
定义。假设临界状态是多价状态,其附加属性是的移动将确定,的移动将确定。
存在临界状态。 证明。从上面我们知道我们以多价状态开始。让完全不动。只要或都不强迫树进入单价状态,就让它移动。等待自由保证了树是有限的,因此在某些时候必须遇到临界状态。
现在考虑一个处于紧急状态的场景。有至少两种可能性:
1)进行移动(从而确定)并停止。然后移动并停止。下一个运行直到完成为止,最终确定。
2)进行移动(从而确定)并停止。下一个运行直到完成,最终决定。不动。
由于原子读取和写入的共识号为1,因此和的移动必须是同一寄存器上的测试设置指令(如果寄存器不同,那么将无法分辨和的顺序。的举动发生了。从的角度来看,情况1和2是无法区分的,因此我们必须让决定和。这是不可能的。
权利要求1和2都遵循测试和设置指令具有2的共识编号。
维基百科的文章确实提供了可以回答您问题的参考,但是您可能不想阅读那篇26页的论文。我将给出(相当技术性)证明的简化版本,以表明测试和设置无法解决3个过程的二进制共识。这种论点被广泛用于证明共识数。
假设我们有一个使用TAS寄存器处理3个进程的共识算法。
在任何时间点,每个进程都会有一个准备执行的移动(指令)。这三个指令中的哪一个将被执行是不确定的。
假设我们处于二价状态(仍然可以同时使用0或1决策的状态),并且无论接下来移动哪个进程,随后的状态都是单价的。由于没有等待,最终必须达到这种状态。
假设(wlg)如果进程1移动,状态将为0价,如果进程2移动,状态将为1价。两次移动都必须是同一寄存器上的TAS操作(或至少是某种写操作),因为如果它们是不同寄存器上的TAS操作,则我们无法确定进程1首先移动还是进程2首先移动。
让我们考虑以下两种可能的执行方式:
从过程3的角度来看,这些状态是无法区分的,因为它只是看到过程2写入的值。但是,在第一种情况下,应将0作为输出,在第二种情况下,应将1作为输出。显然,这是一个矛盾。
进程1和2可以在它们之间决定哪个先移动(因为它们可以在写入之前看到寄存器中的值),而第三个观众进程则不能。
在实践中,一个不太严格的共识定义可能就足够了(在这里我称之为轻共识):
定义。如果(a)每个线程决定相同的值或该值的未知,则在n个线程之间达到“光共识”;(b)至少一个线程知道该值,并且(c)该值实际上是由以下一个提议的线程。
因此,从较轻的意义上说,这种共识允许某个线程不知道该共识,即所确定的价值。
推论:在这种较轻的意义上,测试和设置具有无限的光共识数。
主张:这种较轻的感觉是可行的。例如,为了选择进入关键部分的线程,就不必严格意义上达成共识。也就是说:每个线程都必须知道是否已选择它,但是,如果未选择它,则不必知道已选择了哪个线程。换句话说,对于相互排斥来说,不需要严格的共识,光就足够了。