Lamport算法

来源:互联网 发布:狙击精英 知乎 编辑:程序博客网 时间:2024/05/17 18:12

Lamport

  Lamport算法:又称面包房算法,先来先服务算法。跟很多银行采用的排队机制一样。客户到了银行,先领取一个服务号。一旦某个窗口出现空闲,拥有最小服务号的客户就可以去空闲窗口办理业务。
  Lamport算法利用前述的事件定序方案统一定序所有对临界段的请求,按先来先服务的原则让请求临界资源的进程进入其临界段,进/出临界段1次需要3×(n-1)条消息。
  Lamport算法基本假定如下:
  A. 进程Pi发送的请求消息形如request(Ti , i),其中Ti = Ci是进程Pi发送此消息时对应的逻辑时钟值,i代表消息内容。
  B.每个进程保持一个请求队列,队列中的请求消息根据Þ关系定序,队列初始为空。
  Lamport算法描述
  当进程Pi请求资源时,它把请求消息request(Ti , i)排在自己的请求队列中,同时也把该消息发送给系统中的其他进程; 当进程Pj接收到外来消息request(Ti , i)后,发送回答消息reply(Tj , j),并把request(Ti , i)放入自己的请求队列。应当说明,若进程Pj在收到request(Ti , i)前已提出过对同一资源的访问请求,那么其时间戳应比(Ti , i)小。 若满足下述两条件,则允许进程Pi访问该资源(即允许进入临界段):
  A. Pi自身请求访问该资源的消息已处于请求队列的最前面;
  B. Pi已收到从所有其他进程发来的回答消息,这些回答消息的时间戳均晚于(Ti, i). 为了释放该资源,Pi从自己的队列中撤销请求消息,并发送一个打上时间戳的释放消息release给其他进程;
  当进程Pj收到Pi的release消息后,它撤销自己队列中的原Pi的request(Ti , i)消息。
  下面是我写的代码
  procedure Procesus is
  type MsgTypes is (REQUETE, QUITTANCE, LIBERE);
  task TacheUsager;
  task ExcluionMutuelle is
  entry demande;
  entry attente;
  entry fin;
  entry recoit(msgType : in MsgType; estampille, emetteur : in integer);
  end ExcluionMutuelle;
  task body TacheUsager is
  begin
  ExclusionMutuelle.demande;
  ExclusionMutuelle.attente;
  ExclusionMutuelle.fin;
  ....
  ....
  end TacheUsager;
  task body ExclusionMutuelle is 
  me: constant := ...;
  N : constant := ...;
  Time_Logique : integer:= 0;
  scAccorde : boolean := false;
  type t_file is record
  msgType : msgTypes := LIBERE;
  estampille : integer := 0;
  end record;
  file array (1..N) if t_file;
  function Permission (me : in integer) return boolean is
  accord : boolean := true;
  begin
  for j in 1..N loop
  if j/= me then
  accord := accord and (file(me).estampille < file(j).estampille) or (file(me).estampille = file(j).estampille and me < j);
  end if;
  end loop;
  return accord;
  end Permission;
  begin -- ExclusionMutuelle
  loop
  select
  accept demande;
  Time_Logique := Time_Logique +1;
  file(me) := (REQUETE, Time_Logique);
  for j in 1..N loop
  if j/= me then sent((REQUETE, Time_Logique, me),j);
  end if;
  end loop;
  scAccorde := Permission(me);
  or
  when scAccorde => accept attente;
  or 
  when seAccorde => accept fin;
  file(me):= (LIBERE, Time_Logique);
  for j in 1..N loop
  if j/= me then sent((LIBERE, Time_Logique, me) j);
  end if
  end loop;
  scAccord := false;
  or 
  accept recoit(msgType : in MsgTypes; estampille, emetteur : in integer) do
  Time_Logique := integer'max(Time_Logique, estampille) + 1;
  case msyType is
  when REQUETE => file(emetteur) := (REQUETE, estampille);
  sent((QUITTANCE, Time_Logoque, me), emetteur);
  when LIBERE => file(emetteur) := (LIBERE, estampille);
  when QUITTANCE => if file(emetteur).msgType /= REQUETE then
  file(emetteur) := (QUITTANCE, estampille);
  end if
  end case;
  scAccorde := file(me).msgType = REQUETE and then Permission(me);
  end recoit;
  end select;
  end loop;
  end ExclusionMutuelle;
  end Processus;

http://zh.wikipedia.org/wiki/Lamport%E9%9D%A2%E5%8C%85%E5%BA%97%E7%AE%97%E6%B3%95


0 0
原创粉丝点击