distributed algorithms - ricart agrawala mutual exclusion datum: 26. juni 2000 vortragende:
DESCRIPTION
Distributed Algorithms - Ricart Agrawala Mutual Exclusion Datum: 26. Juni 2000 Vortragende: Thomas Lehner Rene Mayrhofer. Problemstellung. gegeben: - asynchrones Netzwerk - eine Ressource - mehrere konkurrierende Prozesse und deren User gewünscht: - PowerPoint PPT PresentationTRANSCRIPT
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
Distributed Algorithms -Ricart Agrawala Mutual
Exclusion
Datum:
26. Juni 2000Vortragende:
Thomas LehnerRene Mayrhofer
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
Problemstellunggegeben:
- asynchrones Netzwerk- eine Ressource- mehrere konkurrierende Prozesse und deren User
gewünscht:- immer nur ein Prozess greift zugleich auf Ressource zu
Beispiel: Drucker
Grundlegende Idee des Ricart Agrawala Algorithmus:- Einführung einer Critical Region- Prozesse dürfen nur aus dieser auf Ressource zugreifen- Prozesse sprechen sich untereinander ab, so dass sich immer nur einer zugleich in
der Critical Region befindet
exklusiver Zugriff auf Ressource
Problemlösung
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
Problemlösung
1
i
j
Ui
tryi
criti
exiti
remi
ProzesseInteraktionenUser
User-Prozess Interaktion: Einzuhaltende Bedingungen:Well-formedness:- die User-Prozess Interaktion ist wohlgeformt
Mutual exclution:- es ist kein globaler Zustand erreichbar, in dem sich mehr als ein Prozess in C befindet
Progress:- wenn kein Prozess in C und zumindest einer in T ist, dann muss irgendwann einer in C eintreten- wenn zumindest ein Prozess in E ist, erreicht irgendwann einer auch R
Lockout-freedom:- wenn alle User C immer verlassen, dann kommt ein Prozess der in T ist auch irgendwann in C- jeder der in E ist kommt auch irgendwann in R
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
Der Ricart AgrawalaME Algorithmus
- Jeder Prozess besitzt eine logische Uhr. Diese wird erhöht bei jedem Empfangs-/Sendeereignis und bei jeder User-Prozess Interaktion.
- Es existieren die beiden Nachrichten TRY und OK.
- Ein Prozess i kann nur dann in C eintreten, wenn er ein TRY-Broadcast durchgeführt hat und von alle anderen Prozessen die dazugehörigen OK’s erhielt.
- Ein Prozess i darf nur dann mit einem OK auf ein (“try”,c) von j antworten wenn: 1. Pi ist in E, R oder in T und das tryi wurde noch nicht versand. 2. Pi ist in T und (c,j)<(c´,i) mit (c´,“try“) ist letztes TRY von Pi
- In allen anderen Fällen wird das OK für Pj zwischengespeichert und erst in E an Pj versand.
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
Beweis für SafetyBeweis für Mutual Exclution durch indirekte Beweisführung:
Annahme: Pi und Pj sind zu gleich in C mit (c(last tryi),i)<(c(last tryj),j)
es existieren die dazugehörigen zwei TRY und OK Nachrichten, die von Pj an Pi bzw. von Pi an Pj geschickt wurden, bevor die Prozesse in C eintraten
zwei Mögliche Zeitpunkte an denen das TRY von Pj bei Pi ankam:
- i hat sein TRY noch nicht versendet: dann kann Pi kein TRY mit (c,i)<(c(last tryj),j) mehr broadcasten
- i hat sein TRY bereits abgeschickt: dann kann Pj kein OK von Pi erhalten, da ja nach Annahme gilt (c(last tryi),i)<(c(last tryj),j) und somit Pi das OK zurückhält bis Region Ei erreicht wird
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
Beweis für Liveness·Beweis für Progress: (für Region E trivial)
- Der Beweis für die Region T durch indirekten Beweis: Annahme: Zum Zeitpunkt a ist zumindest ein Prozess in T und keiner erreicht je C --> es existiert ein Zeitpunkt b vor a an dem alle Prozesse in R oder in T bleiben --> es existiert ein Zeitpunkt c nach b an dem alle Prozesse in T ihre TRY versand haben und keine dieser Nachrichten mehr in den Nachrichtenkanälen ist --> für einen Pi in T gilt nun: (c(latest Tryi),i)<(c(latest Tryj),j) für alle Pj in T Da Pi nicht in C eintritt, muss es mindestens einen Pj geben dessen OK fehlt Die 2 Gründe, weshalb Pj das OK zurückhalten kann: - Pj ist in C. Widerspruch, da Pj in R oder in T ist - Pj ist in T und erhielt ein Tryj mit (c(Tryj),j)<(c(latest Tryk),k) für alle Pk in T (k j) Widerspruch, da gilt: (c(latest Tryi),i)<(c(latest Tryj),j)
·Beweis für Lockout-freedom: (für Region E trivial)
- Der Beweis für die Region T durch indirekten Beweis: Annahme: Pi ist in T mit versendetem TRY und tritt nie in C ein nach dem maximal n*(c(latest tryi)-1) + i-1 mal ein Prozess in C eintrat, tritt kein weiterer Pj (ji)mehr in C ein, da dann gelten würde (c(latest tryj),j)>(c(latest tryi),i) Widerspruch zu Beweis von Progress
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
Node i ( i {1, ....., N} ):
Signature:Input:
tryi
exiti
recieve(m)j, i, m {"try", "ok"} N, 1 <= j <= N
Output:criti
remi
send(m)i, j, m {"ok"} N, j i
bcast(m)i, m {"try"} N
State Variables:regioni {R, T, C, E}, initially R
clocki N, initially 0
bcast-bufferi, a FIFO queue of {"try"}, initially emptyfor every j, 1 <= j, <= N:
history(j)i, a subset of {"try", "ok"} N, initially {}for every j ¹ i:
send-buffer(j)i, a FIFO queue of {"ok"}, initially empty
deferred-ok(j)i, a FIFO queue of {"ok"}, initially empty
Transitions:tryi
Effect:
clocki := clocki + 1
regioni := T
add ("try") to bcast-bufferi
recieve(m, c)j, i
Effect:clocki := max(clocki, c) + 1
history(j)i := history(j)i {(m, c)}if m = "try" and j i then if regioni {E, R} or (regioni = T and bcast-bufferi contains ("try")) then
add ("ok") to send-buffer(j)i
else if regioni = C then
add ("ok") to deferred-ok(j)i
else if regioni = T and not bcast-bufferi contains ("try")
if (c', i) > (c, j) with ("try", c') history(i)i and
(c'' with ("try", c'') history(i)i and c'' > c') then
add ("ok") to send-buffer(j)i
elseadd ("ok") to deferred-ok(j)i
Formale Spezifikation - 1
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
exiti
Effect:clocki := clocki + 1
regioni := Efor all j i
for all (m, c) in deferred-ok(j)i
add (m, c) to send-buffer(j)i
clear deferred-ok(j)i
criti
Precondition:regioni = T
for such a c that ("try", c) history(i)i and (c'' with ("try", c'') history(i)i and c'' > c)for all j i
("ok", c') history(j)i with (c, i) < (c', j)
Effect:
clocki := clock + 1
regioni := C
remi
Precondition:regioni = E
Effect:clocki := clocki +1
regioni = R
send(m, c)i, j
Precondition:m ist first on send-buffer(j)i
c = clocki + 1 Effect:
clocki := clocki +1
remove first element of send-buffer(j)i
bcast(m, c)i
Precondition:m ist first on bcast-bufferi
c = clocki + 1 Effect:
clocki := clocki +1
remove first element of bcast-bufferi
Tasks:{ criti }
{ remi }
{ bcast(m)i }for every j i:
{ send(m)i, j }
Formale Spezifikation - 2
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
package MutualExclusion;
import daj.*;import java.util.*;
public class RicartAgrawala extends Application { public static final int PNUM = 6; public static final int DISTANCE = 70; public static final int BORDER = 40;
....
public void construct() { Node[] nodes = new Node[PNUM]; int i, j; double phi, r = (PNUM * DISTANCE) / (2 * Math.PI);
for (i=0; i<PNUM; i++) { phi = (double) i / PNUM * Math.PI * 2; nodes[i] = node(new Prog(i), new Integer(i).toString(), (int) (r * Math.cos(phi) + r + BORDER), (int) (r * Math.sin(phi) + r + BORDER)); }
for (i=0; i<PNUM; i++) { for (j=0; j<PNUM; j++) { link(nodes[i], nodes[j]);
} } }
....}
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
class Prog extends Program {.../** the node number */
protected int index; /** the region can be either R, T, C or E */ protected int region = R; /** the current clock value */ protected int clock = 0; /** for every node, the message history */ protected Vector[] history = null; /** for every neighbour, the buffer for remembering deferred ok messages until critical region has been left */ protected Vector[] deferred_ok = null; /** the logical time of the last "try" message that has been sent */ protected LogicalTime lastTryTime = null;
/** the default constructor initializes the index and the arrays */ public Prog(int index) { this.index = index; history = new Vector[RicartAgrawala.PNUM]; for (int i=0; i<history.length; i++) history[i] = new Vector(); deferred_ok = new Vector[RicartAgrawala.PNUM]; for (int i=0; i<deferred_ok.length; i++) if (i != index) deferred_ok[i] = new Vector(); else deferred_ok[i] = null; }
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
public void tryRessource() { // single actions must be atomic --> synchronize them synchronized (this) { clock++; region = T; lastTryTime = new LogicalTime(clock, index); out().send(new Msg(Msg.TRY, lastTryTime)); } }
public void freeRessource() { synchronized (this) { clock++; // this does not match the formal specification - the release is // done immediately region = R; for (int i=0; i<deferred_ok.length; i++) if (i != index) { for (int j=0; j<deferred_ok[i].size(); j++) { out(i).send((Msg) deferred_ok[i].get(j)); } deferred_ok[i].removeAllElements(); } } }
public void ressourceAvailable() { // for testing purposes there is no user to ne notified }
public void ressourceFreed() { // for testing purposes there is no user to ne notified }
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
public void main() { Random rand = new Random(); GlobalAssertion safety = new CriticalRegionConflict(), liveness = new CriticalRegionLockout();
while (true) { assert(safety); assert(liveness); /* first the tree construction routines */ int received = in().select(2); if (received >= 0) { synchronized (this) { Msg msg = (Msg) in(received).receive(); if (msg.time.clock > clock) clock = msg.time.clock; clock++; history[received].add(msg); // respond to try requests from other nodes if (msg.type == Msg.TRY && received != index) handleTryMessage(received, msg); // check if the critical region can be entered now if (region == T && checkOkMsgsReceived()) { clock++; region = C; // the last try is invalid now lastTryTime = null; } } } // simulate the user here ...
} }
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
private void handleTryMessage(int received, Msg msg) { Msg ackMsg = new Msg(Msg.OK, new LogicalTime(clock, index)); if (region == R /*|| region == E*/) out(received).send(ackMsg); else if (region == C) deferred_ok[received].add(ackMsg); else if (region == T) { if (lastTryTime != null && msg.time.lessThan(lastTryTime)) out(received).send(ackMsg); else deferred_ok[received].add(ackMsg); } }
private boolean checkOkMsgsReceived() { boolean receivedOkMsgs = true; for (int i=0; i<history.length; i++) { if (i != index) {
int j = history[i].size() - 1; while (j >= 0 && ((Msg) history[i].get(j)).type != Msg.OK) j--; if (j >= 0) { Msg lastMsg = (Msg) history[i].get(j); if (! lastTryTime.lessThan(lastMsg.time))
receivedOkMsgs = false; } else receivedOkMsgs = false; } } return receivedOkMsgs;
}}
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
class LogicalTime { /** the clock value */ public int clock; /** for equal clock values the sender process's index is compared */ public int process;
public LogicalTime(int clock, int process) { this.clock = clock; this.process = process; }
public boolean equals(Object o) { if (o instanceof LogicalTime && ((LogicalTime) o).clock == clock && ((LogicalTime) o).process == process) return true; else return false; }
public boolean lessThan(LogicalTime t) { if (clock < t.clock || (clock == t.clock && process < t.process)) return true; else return false; }}
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
class CriticalRegionConflict extends GlobalAssertion { private Vector procsInCR = new Vector(); public boolean assert(Program progs[]) { int numOfProcsInCR = 0; procsInCR.removeAllElements(); for (int i=0; i<progs.length; i++) { if (((Prog) progs[i]).region == Prog.C) { numOfProcsInCR++; procsInCR.add(new Integer(i)); } } return numOfProcsInCR <= 1; } public String getText() { String text = "Processes in the critical region: "; for (int i=0; i<procsInCR.size(); i++) text += procsInCR.get(i) + " "; return text; }}
Distributed Algorithms - Ricart Agrawala Mutual Exclusion
2000-06-26Thomas Lehner, Rene Mayrhofer
class CriticalRegionLockout extends GlobalAssertion { private LogicalTime[] tryTimes = new LogicalTime[RicartAgrawala.PNUM]; private int procInCR = -1, procTryingLonger = -1; public CriticalRegionLockout() { for (int i=0; i<tryTimes.length; i++) tryTimes[i] = null; } public boolean assert(Program progs[]) { for (int i=0; i<progs.length; i++) if (((Prog) progs[i]).region == Prog.T) tryTimes[i] = ((Prog) progs[i]).lastTryTime; // Now check when a process is in the CR, if another one is still // trying but started to try earlier. This should not happen. for (int i=0; i<progs.length; i++) if (((Prog) progs[i]).region == Prog.C) { for (int j=0; j<progs.length; j++) { if (((Prog) progs[j]).region == Prog.T && tryTimes[j].lessThan(tryTimes[i])) { procInCR = i; procTryingLonger = j; return false; } } } return true; }}