Κατανεμημένα Συστήματα Ι 1 Περίληψη Φροντιστηρίου 2 Το Περιβάλλον DAP Φροντιστήριο Ένα παράδειγμα υλοποίησης στο DAP Δευτέρα 14 Νοεμβρίου 2005 Γιάννης Κρομμύδας Το περιβάλλον DAP Τι είναι Το περιβάλλον DAP - Χαρακτηριστικά 3 4 Distributed Algorithms Platform: Είναι ένα περιβάλλον ανάπτυξης κατανεμημένων αλγορίθμων το οποίο βασίζεται και επεκτείνει τη βιβλιοθήκη LEDA. Επιτρέπει υλοποίηση και εξομείωση κατανεμημένων αλγορίθμων. Παρέχει γραφικό περιβάλλον (GUI), μέσω του οποίου μπορούμε να ελέγχουμε την εξομείωση. Οι αλγόριθμοι γράφονται σε C++, και όχι σε μια ειδική γλώσσα, όπως σε άλλα περιβάλλοντα.
Η βιβλιοθήκη LEDA Τι είναι 5 Αρχιτεκτονική του DAP 6 Μια βιβλιοθήκη αποδοτικών δομών δεδομένων και αλγορίθμων. Παρέχει δομές που καθιστούν ευκολότερο τον σχεδιασμό και ανάπτυξη αλγορίθμων. Ορθότητα και αποδοτικότητα: Χρησιμοποιεί αξιόπιστους και δοκιμασμένους αλγορίθμους. Παρέχει γραφικό περιβάλλον, όπου εύκολα μπορούμε να δημιουργήσουμε τοπολογίες. Η βιβλιοθήκη libdap 7 Η βιβλιοθήκη libdap 8 // Required by DAP #include DapSystem.h int main(int argc, char **argv) { // Required by DAP, has to be 1st line DapSystem dap(argc, argv); int myid = dap.getmyid(); int getmyid() Επιστρέφει το ID που αντιστοιχεί στη συγκεκριμένη διεργασία void getmyneighbors(vector<int> &nb, string which) Συμπληρώνει τα ID των γειτονικών διεργασιών στο διάνυσμα nb. Αν το which είναι all τότε το nb περιέχει όλους τους γείτονες. Αν το which είναι in τότε το nb περιέχει τους εισερχόμενους γείτονες. Αν το which είναι out τότε το nb περιέχει τους εξερχόμενους γείτονες.
Η βιβλιοθήκη libdap 9 Η βιβλιοθήκη libdap 10 bool send(int nodeid, int rcptid, const Message &msg, const string &tag) Στέλνει το μήνυμα msg, με ετικέτα (τίτλο) tag, στη διεργασία με ID ίσο με rcptid, η οποία βρίσκεται στον κόμβο nodeid. Η ετικέτα μπορεί να είναι κενή. bool sendtoport(int portid, const Message &msg, const string &tag) Στέλνει το μήνυμα msg, με ετικέτα (τίτλο) tag, στη διεργασία που αντιστοιχεί στο κανάλι portid. Η ετικέτα μπορεί να είναι κενή. bool receive(int &senderid, const Message &msg, string &tag, bool block) Λαμβάνει το μήνυμα που έφτασε πρώτο στην διεργασία και δεν έχει παραληφθεί ακόμη. Η ταυτότητα του αποστολέα τοποθετείται στο senderid, το μήνυμα στο msg, και η ετικέτα στο tag. Αν το block είναι false τότε αν δεν υπάρχει τέτοιο μήνυμα, η receive() επιστρέφει false, αλλιώς επιστρέφει true. Αν το block είναι true τότε η receive() θα επιστρέψει όταν φτάσει ένα μήνυμα. void setcolor(int num) Ενημερώνει το GUI να αλλάξει το χρώμα του κόμβου στο χρώμα που αντιστοιχεί στο num. Πως κάνουμε compile με τη LEDA Πως κάνουμε compile με το DAP (1) 11 12 Έστω ότι η LEDA βρίσκεται στο /usr/local/leda. Θέτουμε στο ~/.bashrc: export LEDAROOT=/usr/local/LEDA LD_LIBRARY_PATH=/usr/local/LEDA:$LD_LIBRARY_PATH export LD_LIBRARY_PATH Μεταγλώττιση και σύνδεση προγραμμάτων: g++ -I$LEDAROOT/incl -c file.c g++ -L$LEDAROOT file.o -ll -lm Ιεραρχία καταλόγων στο DAP: src: περιέχει τα source αρχεία του DAP incl: περιέχει τα include αρχεία του DAP demo/algorithms: περιέχει τους αλγόριθμους του χρήστη Τα αρχεία που περιέχουν τις τοπολογίες βρίσκονται στον αρχικό κατάλογο του DAP.
Πως κάνουμε compile με το DAP (2) 13 Makefile 14 Τοποθετούμε τον αλγόριθμο μας (έστω prog.c ) στο demo/algorithms. Για να κάνουμε ευκολότερα compile αλλάζουμε την γραμμή: ALGS = στο αρχείο Makefile ως εξής: ALGS = prog και προσθέτουμε τις γραμμές: prog: prog.o $(CXX) $(CXXFLAGS) -o prog prog.o -L../.. $(PROCESS_LIBS) (η 2η γραμμή αρχίζει με tab) Όταν έχουμε πολλά αρχεία μπορούμε να χρησιμοποιούμε το εργαλείο make για να ελέγχει ποια αρχεία έχουν αλλάξει και να τα μεταγλωτίζει αυτόματα. Χρειαζόμαστε ένα αρχείο που θα ονομάζεται Makefile. Το Makefile περιέχει κανόνες της μορφής: target: dependencies action1 Makefile - Παράδειγμα Makefile - Παράδειγμα 15 16 all: test test2 test: test.o g++ -o test test.o test.o: test.c g++ -c test.c -o test.o test2: test2.o g++ -o test2 test2.o test2.o: test2.c g++ -c test2.c -o test2.o clean: rm -f *.o test test2 Για να μεταγλωττίσουμε όλα τα αρχεία δίνουμε: make all Για να μεταγλωττίσουμε ένα συγκεκριμένο αρχείο δίνουμε: make όνομα_αρχείου Για να σβήσουμε όλα τα εκτελέσιμα δίνουμε: make clean
Το γραφικό περιβάλλον του DAP 17 Ένα παράδειγμα υλοποίησης 18 New Topology / Load Topology / Edit Topology: Δημιουργούμε μια νέα τοπολογία ενός δικτύου ή φορτώνουμε ή επεξεργαζόμαστε μια υπάρχουσα. Start / Stop / Pause / Resume: Ελέγχουμε την εκτέλεση της εξομείωσης του αλγορίθμου. Show Event Log: Δείχνει τα γεγονότα της εξομείωσης π.χ. ποια διεργασία στέλνει μήνυμα κλπ Show Statistics; Δείχνει τον αριθμό των μηνυμάτων που στάλθηκαν. Θα εξετάσουμε πως υλοποιείται ο αλγόριθμος εκλογής αρχηγού LCR στο περιβάλλον DAP. Το πρόβλημα εκλογής αρχηγού 19 Το περιβάλλον εργασίας 20 Η εκλογή αρχηγού σε ένα δίκτυο απαιτεί την επιλογή μιας μοναδικής διεργασίας που θα βρεθεί στην κατάσταση αρχηγός (ή εκλεγμένη ) ενώ όλες οι άλλες διεργασίες βρίσκονται στην κατάσταση μη-αρχηγός (ή μη-εκλεγμένη ). Το πρόβλημα της εκλογής αρχηγού παρουσιάστηκε για πρώτη φορά από τον LeLann (1977). Το πρόβλημα της εκλογής αρχηγού παρουσιάζει πολλές παραλλαγές Μελετάμε την περίπτωση όπου όλες οι διεργασίες τερματίζουν. Θεωρούμε ένα σύγχρονο κατανεμημένο σύστημα από n διεργασίες. Είναι τοποθετημένες σε ένα δίκτυο δακτυλίου. Οι διεργασίες έχουν μοναδικές ταυτότητες. Δεν γνωρίζουν την ταυτότητα των υπόλοιπων διεργασιών. Μπορούν να ξεχωρίσουν τον δεξιόστροφο γείτονα τους από τον αριστερόστροφο.
Το περιβάλλον εργασίας 21 Ο αλγόριθμος LCR 22 Οι διεργασίες διατηρούν μια μεταβλητή leader η οποία αρχικά είναι false. Οι διεργασίες εκπέμπουν την ταυτότητα τους στον δεξιόστροφο γείτονα τους. Μόλις λάβουν μία ταυτότητα απο τον αριστερόστροφο γείτονα, την συγκρίνουν με την δικιά τους. Αν είναι μεγαλύτερη, την προωθούν στον δεξιόστροφο γείτονα. Αν είναι μικρότερη, δεν κάνουν τίποτα. Αν είναι ίδια, μεταβαίνουν στην κατάσταση αρχηγός όπου: Θέτουν την μεταβλητή leader στην τιμή true. Εκπέμπουν το μήνυμα (-1 ταυτότητα) στον δεξιόστροφο γείτονα. Τερματίζουν, επιστρέφοντας την τιμή true. Οι διεργασίες που λαμβάνουν το μήνυμα (-1 ταυτότητα) απο τον αριστερόστροφο γείτονα, μεταβαίνουν στην κατάσταση μη-αρχηγός, όπου: Προωθούν το μήνυμα στον δεξιόστροφο γείτονα Τερματίζουν, επιστρέφοντας την τιμή false. Ψευδοκώδικας του LCR 23 Κώδικας του LCR στο DAP (1) 24 void main() { bool leader = false; int id = getmyid(); sendmessage(id); while (int msg = readmessage()) if (msg.id > id) sendmessage(msg); else if (msg.id == id) { leader = true; sendmessage(-1 * id); exit(true); else if (msg.id < 0) { sendmessage(msg); exit(false); #include "DapSystem.h" /* required by DAP */ #include "impl/client/message/stringmessage.h" const int NEXT = 1; // port to next node int main(int argc, char **argv) { /* required by DAP, has to be 1st line */ DapSystem dap(argc, argv); int mycode = dap.getmyid(); int maxcode = mycode; int incode; int previousid; string tag = "lcrtag"; int finished = 0;
Κώδικας του LCR στο DAP (2) 25 Κώδικας του LCR στο DAP (3) 26 /* send your code to the next process */ StringMessage msg; msg << mycode; dap.sendtoport(next, msg, tag); while (finished == 0) { StringMessage recv; dap.receive(previousid, recv, tag, true); incode = atoi(recv.tostring().c_str()); if (incode > maxcode) { // forward incoming code StringMessage smsg; smsg << incode; dap.sendtoport(next, smsg, tag); maxcode = incode; else if(incode == mycode) { // I am leader StringMessage smsg; smsg << -mycode; dap.sendtoport(next, smsg, tag); finished = 1; else if (incode < 0) { // I am not leader StringMessage smsg; smsg << incode; dap.sendtoport(next, smsg, tag); finished = -1; Αλληλεπίδραση με το GUI του DAP 27 Αλληλεπίδραση με το GUI του DAP 28 Χρήση χρωμάτων για αναπαράσταση κατάστασης μιας διεργασίας // initializations dap.setcolor(0); // I am leader dap.setcolor(3); // GREEN = 3 // I am not the leader dap.setcolor(2); // RED = 2 Προσθήκη επεξηγηματικών μηνυμάτων // Initializations cout << "Process " << mycode << " started" << endl; // Receive message dap.receive(previousid, recv, tag, true); incode = atoi(recv.tostring().c_str()); cout << "Process " << mycode << " received " << incode << endl; // Exit cout << "Process " << mycode << " exited with value " << finished << endl;
Εκτέλεση Εκτέλεση αλγόριθμου 29 Η διεργασία 70 εκλέγεται αρχηγός Όλες οι διεργασίες τερματίζουν