60 likes | 152 Views
Choose a Leader Example: find extrema in unidirectional ring. There are N processes configured into a unidirectional ring; i.e. For 1<=i<n, process i can communicate with process i+1 and process N can communicate with process 1.
E N D
Choose a Leader Example: find extrema in unidirectional ring There are N processes configured into a unidirectional ring; i.e. For 1<=i<n, process i can communicate with process i+1 and process N can communicate with process 1. Each process has an identification number. The problem is to find the largest such number.
Algorithm : Idea For each process there is a max, a just read number, and a neighbourR. Alg Set max to your own number. Send numbers around once. Tag numbers with tag1 First time around, set neighbourR to the number just read (i.e. process i-1) and then send that number around for second round, with tag2. Second time around, if neighbourR is bigger than just read number and bigger than max, set max to neighbourR and output neighbourR with tag1. Otherwise become inactive. If you are inactive, just pass along numbers. You know you are the winner if you receive your own maximum.
/* Dolev, Klawe & Rodeh * `An O(n log n) unidirectional distributed algorithm for extrema * finding in a circle,' J. of Algs, Vol 3. (1982), pp. 245-260 */#define N 5 /* nr of processes (assume 5) */#define I 3 /* node given the smallest number */#define L 10 /* size of buffer (>= 2*N) */mtype = { one, two, winner };chan q[N] = [L] of { mtype, byte};byte nr_leaders = 0;proctype node (chan in, out; byte mynumber){bit Active = 1, know_winner = 0; byte nr, maximum = mynumber, neighbourR;printf("MSC: %d\n", mynumber);out!one(mynumber);do:: in?one(nr) ->if:: Active -> if:: nr != maximum ->out!two(nr); neighbourR = nr :: else ->/* maximum is greatest number */ know_winner = 1;out!winner,nr;; fi :: else -> out!one(nr) fi
:: in?two(nr) -> if:: Active -> if :: neighbourR > nr && neighbourR > maximum -> maximum = neighbourR; out!one(neighbourR) :: else ->Active = 0 fi :: else ->out!two(nr) /*just pass on number */ fi :: in?winner,nr -> if:: nr != mynumber ->printf("MSC: LOST\n"); :: else ->printf("MSC: LEADER\n"); nr_leaders++; fi; if:: ! know_winner -> out!winner,nr :: else skip fi; breakod}
{byte proc;/* dinky initialisation, give process I smallest number */atomic {proc = 1; do :: proc <= N -> run node (q[proc-1], q[proc%N], (N+I-proc)%N+1); proc++ :: proc > N ->breakod }}
Assertions :: in?one(nr) ->if:: Active -> if:: nr != maximum ->out!two(nr); neighbourR = nr :: else ->/* maximum is greatest number */ know_winner = 1; assert (nr==N) fi … … :: in?winner,nr -> if:: nr != mynumber ->printf("MSC: LOST\n"); :: else ->printf("MSC: LEADER\n"); nr_leaders++;assert (nr_leaders ==1); fi; if:: ! know_winner -> out!winner,nr :: else skip fi; breakod