分布式互斥算法Lamport 算法和Ricart-Agrawala 算法

Posted 白水baishui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式互斥算法Lamport 算法和Ricart-Agrawala 算法相关的知识,希望对你有一定的参考价值。

1. 分布式互斥算法的概念

分布式互斥算法,就是在分布式系统中,通过某种消息传递算法来决定哪个进程可以访问临界区资源(如CPU等)。

如何去评价分布式互斥算法是否达到了这个目的呢?于是就定义出了三个算法指标:

  • ME1 安全性
    至多一个进程在使用临界区,不会有多个进程同时在临界区执行;
  • ME2 活性
    不会发生死锁、饿死现象;
  • ME3 公平性
    进程顺序执行(FIFO),先到先进。

能满足这三个条件的算法,就是一个良好的分布式互斥算法。

2. Lamport 算法

某个进程 p i p_i pi 请求临界区时,会先向所有其他进程发送请求 R e q u e s t ( t i , p i ) Request(t_i,p_i) Request(ti,pi),其他进程将这个请求保存到本地请求队列里。

其他进程(接收到请求的进程)如果收到了一个请求,那么会按请求中打上的时间戳 t i t_i ti将请求加入到本地请求队列里,然后返回一个 R e p l a y ( t j ) Replay(t_j) Replay(tj) t j t_j tj是指进程 p j p_j pj 收到进程 p i p_i pi 请求时的时间戳。

p i p_i pi 发送了请求以后进程就等啊等啊,直到:

  1. 进程 p i p_i pi 收到了所有其他进程返回的 R e p l a y ( t ∗ ) Replay(t_*) Replay(t),显然 t ∗ > t i t_*>t_i t>ti,因为其他进程一定是在接收到 p i p_i pi 请求后才打的时间戳(我发了消息后,对方才会回复的消息);
  2. 此时本地请求队列里 t i t_i ti在队头,其他 t ∗ t_* t t i t_i ti后面。

那么此时进程 p i p_i pi 就可以进入临界区执行了。在进程 p i p_i pi 退出临界区时从本地队列里删掉自己的请求 R e q u e s t ( t i , i ) Request (t_i,i) Request(ti,i),再带着时间戳发一个 R e l e a s e Release Release广播,通知所有队列都可以删掉请求了。

Lamport算法起作用的基础很明显是要满足M3的,也即请求的存储要求FIFO,如果非FIFO的话,连续发两个请求返回值的顺序可能就会乱了。

如下图:
下面的进程在时刻 2 2 2给请求A打了一个时间戳,在时刻 4 4 4给请求B打了一个时间戳,但回复B却优先与回复A返回,进程不满足进入临界区的条件,算法就卡死在这里了。

3. Ricart-Agrawala 算法

Lamport 算法的不足之处在于:

  • 没有申请临界区资源的其他进程是没必要知道申请了临界区资源的进程是否释放( R e l e a s e Release Release操作)了临界区资源的。

所以 R e p l a y Replay Replay操作没必要进行的太早,早回复了也进不去临界区,因此不如等到 R e l e a s e Release Release 后在 R e p l a y Replay Replay

针对上述问题,提出了Ricart-Agrawala 算法进行了改进。

首先,某个进程 p i p_i pi 请求临界区时,还是会先向所有其他进程广播请求 R e q u e s t ( t i , p i ) Request(t_i,p_i) Request(ti,pi),其他进程将这个请求保存到本地请求队列里。

其他进程(接收方)收到请求时:

  • 如果自己没有请求临界区,也没有在临界区执行,那就直接 R e p l a y Replay Replay
  • 如果自己正在请求临界区,但是接收方发出的请求的时间戳大于请求消息的时间戳时,也直接 R e p l a y Replay Replay
  • 如果不是上述两种情况,也就是说,接收方收到这个请求消息之后,发现自己需要比这个请求更早的进入临界区,那就先不对它 R e p l a y Replay Replay,而是记录本地的一个数组 R D [ p i ] = 1 RD[p_i]=1 RD[pi]=1,表示延迟回复进程 p i p_i pi 一个请求。

同样的,一个进程只有在收到其他所有进程的 R e p l a y Replay Replay后,才能进入临界区执行。退出临界区时要按照 R D RD RD数组中的记录,将延迟的 R e p l a y Replay Replay发送出去。

可以看出来,Ricart-Agrawala 算法去掉了 R e l e a s e Release Release 消息,也就是说,当一个进程退出临界区之后,通知其他进程可以进入临界区的信号不再特意通过一个 R e l e a s e Release Release信号去通知了,而是通过补全延迟的 R e p l a y Replay Replay信号使其他进程满足进入临界区的条件(此时上一个进程已经释放了临界区资源),然后直接进入临界区就可以了。

4. 算法分析

对于Lamport 算法和Ricart-Agrawala 算法来说,最重要的区别就是Ricart-Agrawala 算法在退出临界区时不再发出 R e l e a s e Release Release消息。下面我们分别来证明一下这两个算法满足了ME1、ME2、ME3。

  1. ME1
    Lamport:如果两个进程 p i p_i pi p j , ( i ≠ j ) p_j,(i\\neq j) pj,(i=j)能同时进入临界区,那么这两个进程必须已经互相向对方发送了 R e p l a y Replay Replay消息。但是,因为 < t i , p i > <t_i, p_i> <ti,pi>对是在队列中排序的,所以 R e p l a y Replay Replay一定是有先后顺序的,只有当某个进程从临界区退出时广播了 R e l e a s e Release Release信号后,另一个进程才能进入临界区。
    Ricart-Agrawala:如果两个进程 p i p_i pi p j , ( i ≠ j ) p_j,(i\\neq j) pj,(i=j)能同时进入临界区,那么这两个进程必须已经互相向对方发送了 R e p l a y Replay Replay消息。但是,因为 < t i , p i > <t_i, p_i> <ti,pi>对是在队列中排序的,所以 R e p l a y Replay Replay一定是有先后顺序的,只有当某个进程从临界区退出后才会发送之前延迟的 R e p l a y Replay Replay信号,另一个进程才能获得 R e p l a y Replay Replay进入临界区。
  2. ME2
    Lamport:假设进程 p i p_i pi 在临界区中执行完毕,那么在它离开临界区时,会广播 R e l e a s e Release Release信号,该信号相当于通知其他进程临界区已被释放,此时新的进程就可以进入临界区,无死锁。
    Ricart-Agrawala:假设进程 p i p_i pi 在临界区中执行完毕,那么在它离开临界

    以上是关于分布式互斥算法Lamport 算法和Ricart-Agrawala 算法的主要内容,如果未能解决你的问题,请参考以下文章

    分布式互斥算法Lamport 算法和Ricart-Agrawala 算法

    《算法之美》---进程互斥软件算法(Lamport面包店算法和Eisenberg算法)

    chandy-lamport 分布式一致性快照 算法详细介绍

    原创一步一步理解Paxos算法

    探索Paxos一致性算法

    Paxos算法详解