算法产生于局部令牌环网:
当令牌在环网中丢失,需要重新产生一个令牌,这就相当于产生一个领导者。这个领导者要求唯一。
定理:
如果每一个进程都相同,则无法选举出唯一领导者。(如果每个进程都相同,则在同步系统运行中,每个进程发出的消息,接收的消息,状态的变化都相同,会同时进入领导者状态)
基本算法 LCR算法:
每个进程都沿环网发送自己的标示符uid(各不相同),并且接受发过来的标示符。
- 接受的标示符 > 自己的标示符,继续转发
- 接受的标示符 < 自己的标示符,丢弃
- 接受的标示符 = 自己的标示符,宣布自己是领导
这也就使得只有uid最大的进程的标号可以围绕环网转一圈。
通信开销:O(n*n)
通信复杂度为O(n*logn)的HS算法:
每个进程传输分为0,1,2...个阶段,每个阶段做以下操作:
- 在L阶段,当前进程 i 向两个方向发送自己进程的uid。每个方向都最多运动2^L跳就折返回原来的进程。(之所以可以降低通信复杂度的一个原因是同时向两边发uid,相对于LCR算法而言可以提前知道有比自己大的uid的进程)
- 如果接收到的uid > 自己的uid,则继续转发
- 如果接收到的uid < 自己的uid,则停止转发
- 如果接收到的uid = 自己的uid,则说明自己发送的uid生存到了最后(转了一圈),所以进程宣布自己是领导。
算法复杂度分析:
在L-1阶段,如果有进程接收到了两个自己之前发出的uid,则说明在2^(L-1)*2+1 = 2^L+1 的范围内,自己是最大的。
n个进程中有多少个可以进入L阶段呢? 就有 n/( 2^L + 1 ) 个,那么L阶段的通信开销为 4*2^L*( n/( 2^L + 1 ) ) <= 4n
一共有 1+logn 轮,所以总消息最多4n*(1+logn)
LCR 和 HS 是基于比较的算法,每个进程不需要知道一共有多少个进程。
一般网络中的领导者选举:
简单洪泛法(每个进程知道网络的直径diam):
每个进程存储自己的uid,作为初始最大uid。
每个进程每一轮向自己的邻居发送目前最大的uid。
接收邻居传过来的uid。
进行diam轮发送,最后最大uid = 自己uid的进程宣称自己是领导者。
优化洪泛算法:
每个进程存储自己的uid,作为初始最大uid。用new-info标记当前收到的消息是之前没收到过的
每个进程每一轮{
如果new-info == true{
向邻居发送最大uid。
}
接收邻居传过来的uid。
if接受的uid > max-uid{ new-info = true }
else{ new-info = false }
}