Κρίσιμη Περιοχή Υπό Συνθήκη (onditional ritical Regions) Ταυτόχρονος Προγραμματισμός 1 lalis@inf.uth.gr
Πέρα από ελεγκτές Ο ελεγκτής είναι χρήσιμο εργαλείο συγχρονισμού παρέχει στον προγραμματιστή εγγυημένο αμοιβαίο αποκλεισμό και (σχετικά) απλό τρόπο συγχρονισμού υψηλότερο επίπεδο αφαίρεσης από τους σηματοφόρους Όμως εξακολουθούν να υπάρχουν προβλήματα ρητή αναμονή και αφύπνιση, συνθήκες ανταγωνισμού ως συνάρτηση του μοντέλου προτεραιότητας, αδιέξοδα Υπάρχουν σχήματα συγχρονισμού ακόμα πιο ψηλού επιπέδου διευκολύνουν ακόμα περισσότερο τον προγραμματισμό ακόμα πιο «προφανής» ορθότητα του κώδικα Ταυτόχρονος Προγραμματισμός 2 lalis@inf.uth.gr
Κρίσιμη περιοχή υπό συνθήκη Δομή συγχρονισμού υψηλού επιπέδου: region R when do S Το νήμα περιμένει στο πλαίσιο συγχρονισμού R, μέχρι η συνθήκη να γίνει αληθής, οπότε και εκτελείται η ομάδα εντολών S Ο έλεγχος της συνθήκης και η εκτέλεση των εντολών S γίνεται με εγγυημένο τον αμοιβαίο αποκλεισμό και την έλλειψη λιμοκτονίας Η έκφραση μπορεί να αναφέρεται σε κοινές μεταβλητές των νημάτων, αλλά δεν μπορεί να αλλάζει τις τιμές τους Ταυτόχρονος Προγραμματισμός 3 lalis@inf.uth.gr
Κρίσιμο τμήμα νήμα : while (1) { region Χ when (true) { do_s1(); } } νήμα : while (1) { region X when (true) { do_s2(); } } Ταυτόχρονος Προγραμματισμός 4 lalis@inf.uth.gr
Παραγωγός-καταναλωτής int avl = 0; παραγωγός: while (1) { } /* produce d */ region X when (avl < Ν) { put(d); avl++; } καταναλωτής: while (1) { } region X when (avl > 0) { d=get(); avl--; } /* consume d */ Ταυτόχρονος Προγραμματισμός 5 lalis@inf.uth.gr
Παραγωγός-καταναλωτής int avl = 0; παραγωγός: while (1) { /* produce d */ region X when (avl < Ν) { avl++; } put(d); καταναλωτής: while (1) { region X when (avl > 0) { avl--; } d=get(); /* consume d */ } } είναι σωστό; Ταυτόχρονος Προγραμματισμός 6 lalis@inf.uth.gr
Συνδαιτυμόνες φιλόσοφοι int avlforks[n]; for (i=0; i<n; i++) { avlforks[i] = 2; } φιλόσοφος i : while (1) { region X when (avlforks[i] == 2) { avlforks[right(i)]--; avlforks[left(i)]--; } /* eat */ region X when (true) { avlforks[right(i)]++; avlforks[left(i)]++; } } Ταυτόχρονος Προγραμματισμός 7 lalis@inf.uth.gr
Αναγνώστες και εγγραφείς int wrs,rds; wrs = 0; rds = 0; εγγραφέας: while (1) { } region X when (wrs+rds == 0) { wrs=1; } /* write data */ region X when (true) { wrs=0; } αναγνώστης: while (1) { } region X when (wrs == 0) { rds++; } /* read data */ region X when (true) { rds--; } Ταυτόχρονος Προγραμματισμός 8 lalis@inf.uth.gr
Αναγνώστες και εγγραφείς int wrs,rds; wrs = 0; rds = 0; εγγραφέας: while (1) { region X when (rds == 0) { /* write data */ αναγνώστης: while (1) { region X when (true) { rds++; } /* read data */ } } region X when (true) { rds--; } Ταυτόχρονος Προγραμματισμός 9 lalis@inf.uth.gr }
Υλοποίηση κρίσιμης περιοχής με σηματοφόρους Ταυτόχρονος Προγραμματισμός 10 lalis@inf.uth.gr
Προσέγγιση Α Για κάθε κρίσιμη περιοχή R (πλαίσιο συγχρονισμού): bsem R_mtx; /* αμοιβαίος αποκλεισμός */ Αμοιβαίος αποκλεισμός για τον έλεγχο της συνθήκης και το παρέχεται μέσω του σηματοφόρου mtx Όσο ένα νήμα δεν μπορεί να εισέλθει στο λόγω του ότι η συνθήκη είναι ψευδής, προσπαθεί ξανά Υπάρχει περίπτωση ενεργής αναμονής Υπάρχει και περίπτωση λιμοκτονίας Ταυτόχρονος Προγραμματισμός 11 lalis@inf.uth.gr
region R; region R when () { S } init(r_mtx,1); down(r_mtx); while (!) { up(r_mtx); yield(); down(r_mtx); } S; up(r_mtx); Ταυτόχρονος Προγραμματισμός 12 lalis@inf.uth.gr
Προσέγγιση Β Για κάθε κρίσιμη περιοχή r (πλαίσιο συγχρονισμού): bsem R_mtx; /* αμοιβαίος αποκλεισμός */ bsem R_q; /* ουρά αναμονής */ int R_n; /* # νημάτων στην ουρά q */ Αμοιβαίος αποκλεισμός για τον έλεγχο της συνθήκης και το παρέχεται μέσω του σηματοφόρου mtx Όσο ένα νήμα δεν μπορεί να εισέλθει στο λόγω του ότι η συνθήκη είναι ψευδής, περιμένει στον σηματοφόρο q Ταυτόχρονος Προγραμματισμός 13 lalis@inf.uth.gr
region R; region R when () { S } init(r_mtx,1); init(r_q,0); R_n = 0; down(r_mtx); while (!) { R_n++; up(r_mtx); down(r_q); } S; if (R_n > 0) {R_n--; up(r_q); } else { up(r_mtx); } Ταυτόχρονος Προγραμματισμός 14 lalis@inf.uth.gr
Αδιέξοδο Έστω πως το μπλοκάρει στην ουρά εν αναμονή της συνθήκης Έστω πως στη συνέχεια μπλοκάρει στην ουρά το που αναμένει μια διαφορετική συνθήκη Αν το αφυπνιστεί και η είναι ψευδής Το θα ξαναμπεί στην ουρά αναμονής Δεν θα αφυπνιστεί το, παρ ότι ίσως ισχύει Το ίσως είναι το μόνο νήμα που μπορεί να κάνει την αληθή... Ταυτόχρονος Προγραμματισμός 15 lalis@inf.uth.gr
Προβληματικό σενάριο (1) αρχική κατάσταση ουρά q Ταυτόχρονος Προγραμματισμός 16 lalis@inf.uth.gr
Προβληματικό σενάριο (2) μπλοκάρει στην ουρά λόγω της συνθήκης Ταυτόχρονος Προγραμματισμός 17 lalis@inf.uth.gr
Προβληματικό σενάριο (3) μπλοκάρει στην ουρά λόγω της συνθήκης Ταυτόχρονος Προγραμματισμός 18 lalis@inf.uth.gr
Προβληματικό σενάριο (4) P3 εισέρχεται στο ΚT ( είναι αληθής) P3 Ταυτόχρονος Προγραμματισμός 19 lalis@inf.uth.gr
Προβληματικό σενάριο (5) P3 εκτελείται στο P3 Ταυτόχρονος Προγραμματισμός 20 lalis@inf.uth.gr
Προβληματικό σενάριο (6) P3 εξέρχεται από, έχοντας κάνει αληθή την, και αφυπνίζει το επόμενο νήμα στην ουρά P3 Ταυτόχρονος Προγραμματισμός 21 lalis@inf.uth.gr
Προβληματικό σενάριο (7) ελέγχει την συνθήκη, που παραμένει ψευδής, και επανατοποθετείται στην ουρά Ταυτόχρονος Προγραμματισμός 22 lalis@inf.uth.gr
Προβληματικό σενάριο (8) το δεν αφυπνίζεται (ποτέ), παρ ότι ισχύει η συνθήκη Ταυτόχρονος Προγραμματισμός 23 lalis@inf.uth.gr
Λιμοκτονία Υπάρχει και περίπτωση προσπεράσματος Έστω πως το μπλοκάρει στην ουρά εν αναμονή της συνθήκης Έστω πως στη συνέχεια μπλοκάρει στην ουρά το που αναμένει την ίδια συνθήκη Αν το αφυπνιστεί ενώ η παραμένει ψευδής το θα ξαναμπεί στην ουρά αναμονής θα βρεθεί πίσω από το που μπορεί να αφυπνιστεί ενώ η ισχύει, να εισέλθει στο, και να ακυρώσει την Αυτό μπορεί να γίνεται επ αόριστο Ταυτόχρονος Προγραμματισμός 24 lalis@inf.uth.gr
Λύση Αν ένα νήμα αφυπνιστεί άσκοπα, για να μη χάσει τη σειρά του, πρέπει να ξαναμπεί στην ουρά, αλλά στην ίδια θέση που είχε προτού ξυπνήσει Χρειάζεται αλυσιδωτή αφύπνιση και επιστροφή στην ουρά όλων των νημάτων που περιμένουν σε αυτή Κατά την διάρκεια αυτής της διαδικασίας, ίσως κάποιο νήμα που βγαίνει από την ουρά να μπορεί να εισέλθει στο (αν η συνθήκη εισόδου του είναι αληθής) Τότε θα πρέπει να μπει στο, χωρίς όμως αυτό να επηρεάζει την επανατοποθέτηση των υπολοίπων νημάτων στην ουρά Επίσης, η επανατοποθέτηση δεν πρέπει να επηρεάζεται από την άφιξη νέων νημάτων Ταυτόχρονος Προγραμματισμός 25 lalis@inf.uth.gr
Επανατοποθέτηση χωρίς είσοδο νήματος στο (1) εκτελείται στο P4 P3 Ταυτόχρονος Προγραμματισμός 26 lalis@inf.uth.gr
Επανατοποθέτηση χωρίς είσοδο νήματος στο (2) εξέρχεται από, αφυπνίζοντας το επόμενο νήμα στην ουρά, ενώ η συνθήκη παραμένει ψευδής P4 P3 Ταυτόχρονος Προγραμματισμός 27 lalis@inf.uth.gr
Επανατοποθέτηση χωρίς είσοδο νήματος στο (3) ελέγχει την συνθήκη, και ξαναμπαίνει πίσω στην ουρά, αφυπνίζοντας πρώτα το επόμενο νήμα P4 P3 Ταυτόχρονος Προγραμματισμός 28 lalis@inf.uth.gr
Επανατοποθέτηση χωρίς είσοδο νήματος στο (4) P3 ελέγχει την συνθήκη, και ξαναμπαίνει πίσω στην ουρά, αφυπνίζοντας πρώτα το επόμενο νήμα P4 P3 Ταυτόχρονος Προγραμματισμός 29 lalis@inf.uth.gr
Επανατοποθέτηση χωρίς είσοδο νήματος στο (5) P4 ελέγχει την συνθήκη, και ξαναμπαίνει πίσω στην ουρά, χωρίς να αφυπνίσει το επόμενο νήμα (καθώς ολοκληρώθηκε μια πλήρης «περιστροφή») P3 P4 Ταυτόχρονος Προγραμματισμός 30 lalis@inf.uth.gr
Επανατοποθέτηση χωρίς είσοδο νήματος στο (6) επαναφορά στην «αρχική» κατάσταση P4 P3 Ταυτόχρονος Προγραμματισμός 31 lalis@inf.uth.gr
Επανατοποθέτηση με είσοδο νήματος στο (1) εκτελείται στο P4 P3 Ταυτόχρονος Προγραμματισμός 32 lalis@inf.uth.gr
Επανατοποθέτηση με είσοδο νήματος στο (2) εξέρχεται από, αφυπνίζοντας το επόμενο νήμα στην ουρά, ενώ η συνθήκη είναι αληθής P4 P3 Ταυτόχρονος Προγραμματισμός 33 lalis@inf.uth.gr
Επανατοποθέτηση με είσοδο νήματος στο (3) ελέγχει την συνθήκη, και ξαναμπαίνει πίσω στην ουρά, αφυπνίζοντας πρώτα το επόμενο νήμα P4 P3 Ταυτόχρονος Προγραμματισμός 34 lalis@inf.uth.gr
Επανατοποθέτηση με είσοδο νήματος στο (4) P3 ελέγχει την συνθήκη, και μπαίνει στο, αφυπνίζοντας πρώτα το επόμενο νήμα P4 P3 Ταυτόχρονος Προγραμματισμός 35 lalis@inf.uth.gr
Επανατοποθέτηση με είσοδο νήματος στο (5) P4, χωρίς να ελέγξει την, μπαίνει πίσω στην ουρά, χωρίς να αφυπνίσει το επόμενο νήμα (καθώς ολοκληρώθηκε μια πλήρης «περιστροφή») P4 P3 Ταυτόχρονος Προγραμματισμός 36 lalis@inf.uth.gr
Επανατοποθέτηση με είσοδο νήματος στο (6) επαναφορά στην αρχική κατάσταση (με το P3 να είναι, όπως πρέπει στο ) P4 P3 Ταυτόχρονος Προγραμματισμός 37 lalis@inf.uth.gr
Προσέγγιση Γ Η επανατοποθέτηση νημάτων στην ουρά αναμονής μπορεί να υλοποιηθεί με δύο ουρές αναμονής: bsem R_mtx; /* αμοιβαίος αποκλεισμός */ bsem R_q1,R_q2; /* ουρές αναμονής */ int R_n1,R_n2; /* # νημάτων στις ουρές */ Η επανατοποθέτηση μπορεί να διακοπεί πρόωρα αν ένα νήμα καταφέρει να μπει στο Σε αυτή τη περίπτωση, τα νήματα περιμένουν «κατανεμημένα» σε δύο ουρές μέχρι την απελευθέρωση του Ταυτόχρονος Προγραμματισμός 38 lalis@inf.uth.gr
region R; region R when () { S } init(r_mtx,1); init(r_q1,0); R_n1 = 0; init(r_q2,0); R_n2 = 0; down(r_mtx); while (!) { R_n1++; if (R_n2 > 0) { R_n2--; up(r_q2); } else { up(r_mtx); } down(r_q1); R_n2++; if (R_n1 > 0) { R_n1--; up(r_q1); } else { up(r_q2); } down(r_q2); } S; if (R_n1 > 0) { R_n1--; up(r_q1); } else if (R_n2 > 0) { R_n2--; up(r_q2); } else { up(r_mtx); } Ταυτόχρονος Προγραμματισμός 39 lalis@inf.uth.gr
Παρατηρήσεις Κάθε νήμα που μπλοκάρεται στην συνθήκη εισόδου του, περνάει αρχικά από την πρώτη ουρά και μετά (υποχρεωτικά) από την δεύτερη ουρά Όταν ένα νήμα εξέρχεται από το (οπότε ίσως έχει καταστήσει αληθείς κάποιες από τις συνθήκες εισόδου των νημάτων που περιμένουν) αφυπνίσει το πρώτο νήμα που περιμένει στην πρώτη ουρά ή όταν αυτή είναι κενή το πρώτο νήμα που περιμένει στην δεύτερη ουρά Η διαχείριση των ουρών γίνεται έτσι ώστε να μην γίνονται (επ αόριστο) προσπεράσματα και να μην υπάρχει περίπτωση αδιεξόδου ή λιμοκτονίας Ταυτόχρονος Προγραμματισμός 40 lalis@inf.uth.gr
αρχική κατάσταση ουρά q1 ουρά q2 Ταυτόχρονος Προγραμματισμός 41 lalis@inf.uth.gr
, με βάση την συνθήκη, μπλοκάρει στην ουρά1 Ταυτόχρονος Προγραμματισμός 42 lalis@inf.uth.gr
, με βάση την συνθήκη, μπλοκάρει στην ουρά1 Ταυτόχρονος Προγραμματισμός 43 lalis@inf.uth.gr
P3, με βάση την συνθήκη, εισέρχεται στο P3 Ταυτόχρονος Προγραμματισμός 44 lalis@inf.uth.gr
P3 εκτελείται στο P3 Ταυτόχρονος Προγραμματισμός 45 lalis@inf.uth.gr
P3 εξέρχεται από, έχοντας κάνει αληθή στην συνθήκη, και αφυπνίζει το επόμενο νήμα στην ουρά P3 Ταυτόχρονος Προγραμματισμός 46 lalis@inf.uth.gr
αφυπνίζει το επόμενο νήμα στην ουρά1, και μπαίνει στην ουρά2 Ταυτόχρονος Προγραμματισμός 47 lalis@inf.uth.gr
αφυπνίζει το επόμενο νήμα στην ουρά2 (αφού δεν υπάρχει άλλο νήμα στην ουρά1), και μπαίνει στην ουρά2 Ταυτόχρονος Προγραμματισμός 48 lalis@inf.uth.gr
ελέγχει την συνθήκη, που είναι ψευδής, αφυπνίζει το επόμενο νήμα στην ουρά2 (αφού δεν υπάρχει άλλο νήμα στην ουρά1), και μπαίνει πίσω στην ουρά1 Ταυτόχρονος Προγραμματισμός 49 lalis@inf.uth.gr
ελέγχει την συνθήκη, που είναι αληθής, και εισέρχεται στο Ταυτόχρονος Προγραμματισμός 50 lalis@inf.uth.gr
περιμένει στην ουρά1 Ταυτόχρονος Προγραμματισμός 51 lalis@inf.uth.gr
αρχική κατάσταση Ταυτόχρονος Προγραμματισμός 52 lalis@inf.uth.gr
, με βάση την συνθήκη, μπλοκάρει στην ουρά1 Ταυτόχρονος Προγραμματισμός 53 lalis@inf.uth.gr
P3, με βάση την συνθήκη, εισέρχεται στο P3 Ταυτόχρονος Προγραμματισμός 54 lalis@inf.uth.gr
P3 εκτελείται στο P3 Ταυτόχρονος Προγραμματισμός 55 lalis@inf.uth.gr
P3 εξέρχεται από, χωρίς να ισχύει η συνθήκη, και αφυπνίζει το επόμενο νήμα στην ουρά1 P3 Ταυτόχρονος Προγραμματισμός 56 lalis@inf.uth.gr
αφυπνίζει το επόμενο νήμα στην ουρά1, και μπαίνει στην ουρά2 Ταυτόχρονος Προγραμματισμός 57 lalis@inf.uth.gr
αφυπνίζει το επόμενο νήμα στην ουρά2 (αφού δεν υπάρχει άλλο νήμα στην ουρά1), και μπαίνει στην ουρά2 Ταυτόχρονος Προγραμματισμός 58 lalis@inf.uth.gr
ελέγχει την συνθήκη, που είναι ψευδής, αφυπνίζει το επόμενο νήμα στην ουρά2 (αφού δεν υπάρχει άλλο νήμα στην ουρά1), και μπαίνει πίσω στην ουρά1 Ταυτόχρονος Προγραμματισμός 59 lalis@inf.uth.gr
ελέγχει την συνθήκη, που είναι ψευδής, και μπαίνει πίσω στην ουρά1 Ταυτόχρονος Προγραμματισμός 60 lalis@inf.uth.gr
νήματα περιμένουν στην ουρά1 Ταυτόχρονος Προγραμματισμός 61 lalis@inf.uth.gr
νέο νήμα P4, το οποίο με βάση την συνθήκη εισέρχεται στο P4 Ταυτόχρονος Προγραμματισμός 62 lalis@inf.uth.gr
νήμα P4 εκτελείται στο P4 Ταυτόχρονος Προγραμματισμός 63 lalis@inf.uth.gr
νήμα P4 εξέρχεται από, έχοντας κάνει αληθή την συνθήκη, και αφυπνίζει το επόμενο νήμα στην ουρά1 P4 Ταυτόχρονος Προγραμματισμός 64 lalis@inf.uth.gr
νήμα αφυπνίζει το επόμενο νήμα στην ουρά1 και τοποθετείται στην ουρά2 Ταυτόχρονος Προγραμματισμός 65 lalis@inf.uth.gr
νήμα αφυπνίζει το επόμενο νήμα στην ουρά2 (αφού δεν υπάρχει άλλο νήμα στην ουρά1), και μπαίνει στην ουρά2 Ταυτόχρονος Προγραμματισμός 66 lalis@inf.uth.gr
νήμα ελέγχει συνθήκη, που είναι αληθής, και εισέρχεται στο Ταυτόχρονος Προγραμματισμός 67 lalis@inf.uth.gr
νήμα εκτελείται στο Ταυτόχρονος Προγραμματισμός 68 lalis@inf.uth.gr
νήμα εξέρχεται από, έχοντας κάνει την συνθήκη ψευδή, και αφυπνίζει το επόμενο νήμα στην ουρά2 (αφού δεν υπάρχει άλλο νήμα στην ουρά1) Ταυτόχρονος Προγραμματισμός 69 lalis@inf.uth.gr
ελέγχει την συνθήκη, που είναι ψευδής, και μπαίνει πίσω στην ουρά1 Ταυτόχρονος Προγραμματισμός 70 lalis@inf.uth.gr
περιμένει στην ουρά1 Ταυτόχρονος Προγραμματισμός 71 lalis@inf.uth.gr
Παρατήρηση Η κρίσιμη περιοχή υπό συνθήκη επιτυγχάνει συγχρονισμό σε ακόμα πιο «ψηλό» επίπεδο από τους σηματοφόρους και τους ελεγκτές Ο προγραμματιστής δεν χρειάζεται να ασχοληθεί ούτε με τον αμοιβαίο αποκλεισμό ούτε με την αναμονή νημάτων μέσα στο ούτε με την αφύπνιση τους Μπορεί όμως να υπάρχει αυξημένο κόστος σε ποιο χαμηλό επίπεδο άσκοπες αφυπνίσεις των νημάτων για να πραγματοποιηθεί έλεγχος της συνθήκης αναμονής Ταυτόχρονος Προγραμματισμός 72 lalis@inf.uth.gr