Ορθότητα λειτουργίας τμημάτων λογισμικού & δομών δεδομένων υπό ταυτόχρονη εκτέλεση ΙΙΙ 1 lalis@inf.uth.gr
Ορθή συμπεριφορά τμήματος λογισμικού Ένα τμήμα λογισμικού (ή ένας ΑΤΔ) προσπελάζεται με δομημένο/ελεγχόμενο τρόπο, μέσα από συγκεκριμένες λειτουργίες / πράξεις πρόσβασης Υποθέτοντας μονονηματική/σειριακή εκτέλεση, η επιθυμητή λειτουργικότητα ορίζεται με βάση μια αντικειμενική παρατήρηση της συμπεριφοράς Μια υλοποίηση είναι ορθή/σωστή αν επιτυγχάνει την προσδιορισμένη επιθυμητή λειτουργικότητα (χωρίς να γνωρίζουμε το πως τα καταφέρνει) ΙΙΙ 2 lalis@inf.uth.gr
Ουρά FIFO init(): αρχικοποίηση put(object o): προσθήκη Object get(): αφαίρεση βοηθητική συνάρτηση ISEMPTY() get put init FIFO_Queue 1) init(); ISEMPTY() 2) ISEMPTY() ο=get(); ο == NULL ISEMPTY() μια «τυπική» περιγραφή της ορθής λειτουργίας 3) ISEMPTY() put(x1); put(xn); ο1=get(); οn=get(); o1 == x1 οn == xn ISEMPTY() ΙΙΙ 3 lalis@inf.uth.gr
Ζητούμενο Υποθέτουμε ότι η επιθυμητή λειτουργικότητα έχει προσδιοριστεί για μια σειριακή εκτέλεση Θέλουμε να φτιάξουμε μια υλοποίηση που μπορεί να χρησιμοποιηθεί υπό ταυτόχρονη εκτέλεση Ποιες «συμπεριφορές» είναι επιτρεπτές υπό ταυτόχρονη εκτέλεση; Πως μπορούμε να σκεφτούμε για αυτές, έτσι ώστε να βρούμε τα περιθώρια που (τυχόν) υπάρχουν σε επίπεδο υλοποίησης; ΙΙΙ 4 lalis@inf.uth.gr
Μοντέλο εκτέλεσης Κάθε πράξη πρόσβασης «σπάει» σε δύο μέρη: (1) αίτηση/κλήση, (2) απάντηση/επιστροφή Το διάστημα ανάμεσα στην αίτηση και την απάντηση αντιστοιχεί στην διάρκεια εκτέλεσης της πράξης Ταυτόχρονη εκτέλεση: χρονική επικάλυψη των πράξεων πρόσβασης που εκτελούν τα νήματα ΙΙΙ 5 lalis@inf.uth.gr
Συμβολισμοί op(x,y)p πράξη op, καλείται από το νήμα P με παραμέτρους x και επιστρέφει αποτελέσματα y P op(x) t1 OK(y) t2 η εκτέλεση της op(x,y)p αρχίζει και ολοκληρώνεται τις χρονικές στιγμές t1 και t2 αντίστοιχα ΙΙΙ 6 lalis@inf.uth.gr
Σειρά εκτέλεσης Η πράξη op2(x2,y2) εκτελείται μετά την πράξη op1(x1,y1)p1 αν ισχύει ότι: ΟΚ(y1)P1,,op2(x2) Χρησιμοποιούμε τον συμβολισμό: op1 ; op2 Η πράξη op2(x2,y2) εκτελείται ταυτόχρονα με την πράξη op1(x1,y1)p1 αν ισχύει ότι: op1(x1)p1,,op2(x2),,ok(y1)p1 ή op2(x1),,op1(x2)p1,,ok(y2) Χρησιμοποιούμε τον συμβολισμό: op1 op2 ΙΙΙ 7 lalis@inf.uth.gr
P1 op1(x1) ΟΚ(y1) (1) op2(x2) ΟΚ(y2) P1 op1(x1) ΟΚ(y1) (2) op2(x2) ΟΚ(y2) P1 op1(x1) ΟΚ(y1) (3) op2(x2) ΟΚ(y2) ΙΙΙ 8 lalis@inf.uth.gr
Ιστορία εκτέλεσης Δύο τύποι «γεγονότων»: αιτήσεις και απαντήσεις Ιστορία: ακολουθία γεγονότων που αντιστοιχεί σε μια (αυστηρά σειριακή ή ταυτόχρονη) εκτέλεση Η σειρά των γεγονότων αντιστοιχεί στην χρονική στιγμή «αποστολής» των αιτήσεων op(x)p, και «παραλαβής» των απαντήσεων OK(y)P Τοπικοί κανόνες σωστής μορφοποίησης (ανά νήμα): το αποτέλεσμα μιας πράξης φτάνει μετά την αίτηση η επόμενη αίτηση μπορεί να σταλεί αφού πρώτα παραληφθεί η απάντηση για την προηγούμενη ΙΙΙ 9 lalis@inf.uth.gr
Σειριακή και ταυτόχρονη ιστορία Σειριακή ιστορία: δεν υφίστανται ταυτόχρονες εκτελέσεις πράξεων από διαφορετικά νήματα Κάθε αίτηση op(x)p ακολουθείται από την αντίστοιχη απάντηση OK(y)P χωρίς να μεσολαβεί κάποια άλλη αίτηση ή απάντηση Ταυτόχρονη ιστορία: υπάρχει επικάλυψη ανάμεσα στις πράξεις από διαφορετικά νήματα Ανάμεσα σε κάποια αίτηση op(x)p και την αντίστοιχη απάντηση OK(y)P, παρεμβάλλεται μια άλλη αίτηση op(x) ΙΙΙ 10 lalis@inf.uth.gr
Σειριακή εκτέλεση P1 op1(x1) ΟΚ(y1) op2(x2) ΟΚ(y2) op3(x3) ΟΚ(y3) σειριακή ιστορία op2(x2), OK(y2), op1(x1)p1, OK(y1)P1, op3(x3), OK(y3) ΙΙΙ 11 lalis@inf.uth.gr
Ταυτόχρονη εκτέλεση P1 op1(x1) ΟΚ(y1) op2(x2) ΟΚ(y2) op3(x3) ΟΚ(y3) ταυτόχρονη ιστορία op2(x2), op1(x1)p1, OK(y2), op3(x3), OK(y1)P1, OK(y3) ΙΙΙ 12 lalis@inf.uth.gr
Ορθή σειριακή εκτέλεση Κάθε σειριακή εκτέλεση αντιστοιχεί σε μια μοναδική σειριακή ιστορία Επιτρεπτή σειριακή ιστορία: το αποτέλεσμα των πράξεων είναι συμβατό με τις προδιαγραφές (δεν αντιφάσκουν με την επιθυμητή λειτουργικότητα) Ορθή σειριακή εκτέλεση: η αντίστοιχη σειριακή ιστορία είναι επιτρεπτή ΙΙΙ 13 lalis@inf.uth.gr
FIFO Queue P1 put(a) ΟΚ() get() ΟΚ(b) put(b) ΟΚ() get() OK(a) επιτρεπτή σειριακή ιστορία put(a)p1, OK()P1, put(b), OK(), get(), OK(a), get()p1, OK(b)P1 ΙΙΙ 14 lalis@inf.uth.gr
FIFO Queue P1 put(a) ΟΚ() get() ΟΚ(a) put(b) ΟΚ() get() OK(b) μη επιτρεπτή σειριακή ιστορία put(a)p1, OK()P1, put(b), OK(), get(), OK(b), get()p1, OK(a)P1 ΙΙΙ 15 lalis@inf.uth.gr
Σειριακή ισοδυναμία Μια ταυτόχρονη ιστορία Ι είναι ισοδύναμη με την σειριακή ιστορία Ι αν: 1. Οι πράξεις που έχουν συγκεκριμένη σχετική σειρά στην Ι, έχουν την ίδια σχετική σειρά και στην Ι op1;op2 Ι op1;op2 Ι 2. Οι πράξεις που είναι ταυτόχρονες στην Ι, έχουν μια (οποιαδήποτε) σχετική σειρά στην Ι op1 op2 Ι op1;op2 Ι op2;op1 Ι Μια ταυτόχρονη ιστορία Ι μπορεί να έχει πολλές διαφορετικές ισοδύναμες σειριακές ιστορίες Ι ΙΙΙ 16 lalis@inf.uth.gr
Διαδικασία «κατασκευής» Θεωρούμε ότι κάθε πράξη εκτελείται στιγμιαία (αίτηση και απάντηση συμπίπτουν στον χρόνο) Επιλέγουμε ελεύθερα την χρονική στιγμή εκτέλεσης κάθε πράξης, αρκεί αυτή: (α) να βρίσκεται μέσα στο αρχικό διάστημα εκτέλεσης της πράξης (β) να μην συμπίπτει με κάποια άλλη πράξη Κάθε τέτοιο σενάριο αντιστοιχεί σε μια σειριακή εκτέλεση που είναι ισοδύναμη με την ταυτόχρονη ΙΙΙ 17 lalis@inf.uth.gr
P1 op1(x1) ΟΚ(y1) op2(x2) ΟΚ(y2) op3(x3) ΟΚ(y3) P3 op4(x4) ΟΚ(y4) ΙΙΙ 18 lalis@inf.uth.gr
ισοδύναμη σειριακή εκτέλεση P1 op1(x1) ΟΚ(y1) op2(x2) ΟΚ(y2) op3(x3) ΟΚ(y3) P3 op4(x4) ΟΚ(y4) op4 op2 op1 op3 ΙΙΙ 19 lalis@inf.uth.gr
ισοδύναμη σειριακή εκτέλεση P1 op1(x1) ΟΚ(y1) op2(x2) ΟΚ(y2) op3(x3) ΟΚ(y3) P3 op4(x4) ΟΚ(y4) op2 op1 op3 op4 ΙΙΙ 20 lalis@inf.uth.gr
μη ισοδύναμη σειριακή εκτέλεση P1 op1(x1) ΟΚ(y1) op2(x2) ΟΚ(y2) op3(x3) ΟΚ(y3) P3 op4(x4) ΟΚ(y4) op2 op4 op3 op1 ΙΙΙ 21 lalis@inf.uth.gr
Παρατήρηση Η σχετική σειρά των πράξεων που εκτελούνται σειριακά (στην ταυτόχρονη εκτέλεση) δεν μπορεί να αλλάξει Πιθανώς είναι αποτέλεσμα ρητού (αλλά μη ορατού σε εμάς) συγχρονισμού ανάμεσα στα νήματα Συνεπώς δεν έχουμε «δικαίωμα» να αλλάξουμε την σχετική σειρά αυτών των πράξεων Ουσιαστική ελευθερία επιλογής υπάρχει μόνο ως προς τις ταυτόχρονες (επικαλυπτόμενες) πράξεις Δεν υπάρχει λογική εξάρτηση μεταξύ τους σε επίπεδο εφαρμογής (εκτός αν η εφαρμογή έχει bug) Έχουμε «δικαίωμα» να τις διατάξουμε όπως θέλουμε ΙΙΙ 22 lalis@inf.uth.gr
P1 op1(x1) συγχρονισμός μεταξύ P1 και ΟΚ(y1) παραβίαση λογικής συνέπειας op2(x2) ΟΚ(y2) op3(x3) ΟΚ(y3) P3 op4(x4) ΟΚ(y4) ΙΙΙ 23 lalis@inf.uth.gr
Ορθότητα Μια ταυτόχρονη εκτέλεση είναι ορθή (επιτρεπτή) αν είναι ισοδύναμη με (μπορεί να αντιστοιχηθεί σε) τουλάχιστον μια ορθή σειριακή εκτέλεση ΙΙΙ 24 lalis@inf.uth.gr
FIFO Queue P1 put(a) ΟΚ() get() ΟΚ(a) επιτρεπτή ΙΙΙ 25 lalis@inf.uth.gr
FIFO Queue P1 put(a) ΟΚ() get() ΟΚ(NULL) επιτρεπτή ΙΙΙ 26 lalis@inf.uth.gr
FIFO Queue P1 put(a) ΟΚ() get() ΟΚ(a) επιτρεπτή ΙΙΙ 27 lalis@inf.uth.gr
FIFO Queue P1 put(a) ΟΚ() get() ΟΚ(NULL) επιτρεπτή ΙΙΙ 28 lalis@inf.uth.gr
FIFO Queue P1 put(a) ΟΚ() get() ΟΚ(b) put(b) ΟΚ() μη επιτρεπτή ΙΙΙ 29 lalis@inf.uth.gr
FIFO Queue P1 put(a) ΟΚ() get() ΟΚ(b) put(b) ΟΚ() get() OK(a) επιτρεπτή ΙΙΙ 30 lalis@inf.uth.gr
FIFO Queue P1 put(a) ΟΚ() get() ΟΚ(a) put(b) ΟΚ() get() OK(b) επιτρεπτή ΙΙΙ 31 lalis@inf.uth.gr
FIFO Queue P1 put(a) ΟΚ() get() ΟΚ(a) put(b) ΟΚ() get() OK(a) μη επιτρεπτή ΙΙΙ 32 lalis@inf.uth.gr
Έλεγχος ταυτόχρονης εκτέλεσης Φτιάχνουμε την ταυτόχρονη ιστορία Αν βρούμε έστω και μια επιτρεπτή ισοδύναμη σειριακή ιστορία, τότε η εκτέλεση είναι ορθή Αν ελέγξουμε όλες τις ισοδύναμες σειριακές ιστορίες και καμία από αυτές δεν είναι επιτρεπτή, τότε η εκτέλεση είναι λανθασμένη ΙΙΙ 33 lalis@inf.uth.gr
Πότε είναι μια υλοποίηση σωστή; Όταν κάθε δυνατή ταυτόχρονη εκτέλεση των πράξεων πρόσβασης είναι ορθή Η απλούστερη σωστή υλοποίηση είναι αυτή που εκβιάζει αμοιβαίο αποκλεισμό (άρα και απόλυτη σειριοποίηση) ανάμεσα στις πράξεις πρόσβασης Όμως, αυτό μπορεί να μην είναι ικανοποιητικό από πλευράς απόδοσης ιδίως σε συστήματα με πολλούς επεξεργαστές Μπορούν τμήματα του κώδικα των πράξεων πρόσβασης να εκτελούνται ταυτόχρονα, χωρίς να προκύπτουν προβλήματα ορθότητας; ΙΙΙ 34 lalis@inf.uth.gr