Ελεγκτές/Παρακολουθητές (Monitors) 1 lalis@inf.uth.gr
Ελεγκτές Αμοιβαίος αποκλεισμός στο πλαίσιο ενός τμήματος λογισμικού που προσπελάζεται με δομημένο τρόπο, μέσω προκαθορισμένης διασύνδεσης (API) Ο συγχρονισμός γίνεται την στιγμή που ένα νήμα επιχειρεί να καλέσει μια λειτουργία του ελεγκτή Αν κάποιο άλλο νήμα ήδη εκτελεί μια λειτουργία του ελεγκτή, τότε το καλών νήμα μπλοκάρεται, μέχρι το προηγούμενο νήμα να ολοκληρώσει την λειτουργία Ο αμοιβαίος αποκλεισμός είναι εξ ορισμού εγγυημένος για τον κώδικα που γράφεται μέσα στο πλαίσιο ενός ελεγκτή 2 lalis@inf.uth.gr
entry points mutual exclusion boundary proc3 proc2 proc1 code code code state / data Monitor 3 lalis@inf.uth.gr
proc2 proc1 proc2 proc1 code code (1) (2) state / data code state / data code proc2 proc1 proc2 proc1 code code (3) (4) state / data code state / data code 4 lalis@inf.uth.gr
Δομή κώδικα monitor name { /* δηλώσεις μεταβλητών */ /* ρουτίνες πρόσβασης ελεγκτή */ proc1 ( ) { } proc2 ( ) { } εκτελούνται με εγγυημένο τον αμοιβαίο αποκλεισμό procν ( ) { } } 5 lalis@inf.uth.gr
Κρίσιμο τμήμα monitor cs { } void CS1 () { /* κώδικας που αποτελεί κρίσιμο τμήμα */ } void CSN() { /* κώδικας που αποτελεί κρίσιμο τμήμα */ } : : PN: while (1) { cs.cs1(); } while (1) { cs.cs2(); }... while (1) { cs.csn(); } 6 lalis@inf.uth.gr
με ελεγκτή monitor counter { int cnt; void init() { cnt=0; } με δυαδικό σηματοφόρο int cnt; bsem mtx; void init() { cnt=0; init(mtx,1); } } void inc() { cnt=cnt+1; } void dec() { cnt=cnt-1; } void inc() { down(mtx); cnt=cnt+1; up(mtx); } void dec() { down(mtx); cnt=cnt-1; up(mtx); } 7 lalis@inf.uth.gr
Μεταβλητές συνθήκης Συχνά απαιτείται αναμονή υπό συνθήκη μέσα σε ένα κρίσιμο τμήμα π.χ., αναμονή καταναλωτή όταν/όσο η αποθήκη είναι άδεια Η αναμονή μέσα σε ελεγκτή επιτυγχάνεται με μεταβλητές συνθήκης (condition variables) Η μεταβλητή συνθήκης μπορεί να θεωρηθεί ως μια δίκαιη ουρά αναμονής. Οι μεταβλητές συνθήκης μπορεί να δηλωθούν μόνο μέσα σε έναν ελεγκτή δεν είναι σηματοφόροι 8 lalis@inf.uth.gr
Χρήση μεταβλητών συνθήκης : δήλωση wait(x): το καλών νήμα μπλοκάρεται, ενώ παράλληλα αίρεται ο «συμβατικός» αμοιβαίος αποκλεισμός στον ελεγκτή (γιατί;) signal(x): αφυπνίζεται ένα (το πρώτο) από τα νήματα που έχουν μπλοκάρει στο x Αν δεν υπάρχει μπλοκαρισμένο νήμα στο x, απλά δεν γίνεται τίποτα αν στη συνέχεια ένα νήμα καλέσει wait(x), θα μπλοκάρει 9 lalis@inf.uth.gr
Συνθήκες ανταγωνισμού Με σηματοφόρους, αν ένα νήμα επιθυμεί να περιμένει μέσα στο ΚΤ, πρέπει να απελευθερώσει (up) τον σηματοφόρο που χρησιμοποιείται για αμοιβαίο αποκλεισμό, και να μπλοκάρει (down) μειώνοντας τον σηματοφόρο που χρησιμοποιείται ως ουρά αναμονής Υπάρχει η «κλασική» συνθήκη ανταγωνισμού: πιθανότητα εναλλαγής μετά το up και πριν το down Αυτό το πρόβλημα δεν υφίσταται σε ελεγκτή (όμως: βλέπε ζητήματα προτεραιότητας) 10 lalis@inf.uth.gr
bsem mtx,q; void init() { init(mtx,1); init(q,0); } void proc1( ) { down(mtx); if ( ) { up(mtx);} else { up(mtx); down(q);} } monitor { condition q; void init() { } void proc1( ) { if ( ) { wait(q); } } δεν υφίσταται συνθήκη ανταγωνισμού void proc2( ) { down(mtx); if ( ) { up(q); } up(mtx); } υπάρχει συνθήκη ανταγωνισμού void proc2( ) { if ( ) { signal(q); } } 11 lalis@inf.uth.gr }
Προτεραιότητες (1) Τι γίνεται αν ένα νήμα μέσω signal αφυπνίσει ένα άλλο νήμα που έχει μπλοκάρει μέσα στον ελεγκτή; Για να ισχύει αμοιβαίος αποκλεισμός, μόνο ένα νήμα μπορεί να συνεχίσει την εκτέλεση του στον ελεγκτή signal&continue: προτεραιότητα έχει το νήμα που προκάλεσε την αφύπνιση (κάλεσε την signal) signal&block: προτεραιότητα έχει το νήμα που αφυπνίστηκε (σειρά εισόδου στον ελεγκτή) Δεν τίθεται θέμα αν η signal καλείται ως τελευταία εντολή σε μια ρουτίνα του ελεγκτή γιατί; 12 lalis@inf.uth.gr
πλαίσιο συγχρονισμού του ελεγκτή ουρά αναμονής της μεταβλητής συνθήκης x νήμα που εκτελεί κώδικα του ελεγκτή ουρά νημάτων που περιμένουν, λόγω signal&block / signal&continue, να ελευθερωθεί ο ελεγκτής 13 lalis@inf.uth.gr
call 14 lalis@inf.uth.gr
15 lalis@inf.uth.gr
wait 16 lalis@inf.uth.gr
17 lalis@inf.uth.gr
call 18 lalis@inf.uth.gr
19 lalis@inf.uth.gr
signal 20 lalis@inf.uth.gr
signal&continue signal 21 lalis@inf.uth.gr
signal&continue προσπεράστηκε από 22 lalis@inf.uth.gr
signal&continue exit 23 lalis@inf.uth.gr
signal&continue 24 lalis@inf.uth.gr
signal&continue 25 lalis@inf.uth.gr
signal 26 lalis@inf.uth.gr
signal&block signal 27 lalis@inf.uth.gr
signal&block 28 lalis@inf.uth.gr
signal&block exit 29 lalis@inf.uth.gr
signal&block 30 lalis@inf.uth.gr
signal&block 31 lalis@inf.uth.gr
Προτεραιότητες (2) Τι γίνεται με τα νήματα που έχουν μπλοκάρει έξω από τον ελεγκτή, περιμένοντας να τους δοθεί άδεια να προχωρήσουν με την εκτέλεση μιας λειτουργίας; Eggshell: προτεραιότητα έχουν τα νήματα που ήδη έχουν αρχίσει την εκτέλεση τους μέσα στον ελεγκτή Λογική FIFO Open: τα νήματα έχουν την ίδια προτεραιότητα Ένα νήμα που αφυπνίζει/αφυπνίζεται μέσω signal, μπορεί προσπεραστεί από ένα άλλο νήμα που περιμένει έξω από τον ελεγκτή 32 lalis@inf.uth.gr
Eggshell χαμηλή προτεραιότητα ουρά εισόδου ουρά αναμονής της μεταβλητής συνθήκης x ψηλή προτεραιότητα νήμα που εκτελεί κώδικα του ελεγκτή ουρά νημάτων που περιμένουν, λόγω signal&block / signal&continue, να ελευθερωθεί ο ελεγκτής 33 lalis@inf.uth.gr
eggshell P3 call 34 lalis@inf.uth.gr
P3 eggshell 35 lalis@inf.uth.gr
P3 eggshell signal&block signal 36 lalis@inf.uth.gr
P3 eggshell 37 lalis@inf.uth.gr
P3 eggshell exit 38 lalis@inf.uth.gr
P3 eggshell 39 lalis@inf.uth.gr
P3 eggshell 40 lalis@inf.uth.gr
P3 eggshell exit 41 lalis@inf.uth.gr
P3 eggshell 42 lalis@inf.uth.gr
P3 eggshell 43 lalis@inf.uth.gr
eggshell P3 44 lalis@inf.uth.gr
Open κοινή ουρά (α) για τα νήματα που θέλουν να μπουν στον ελεγκτή και (β) για τα νήματα που είχαν μπλοκάρει λόγω signal μέσα στον ελεγκτή ουρά εισόδου ουρά αναμονής της μεταβλητής συνθήκης x νήμα που εκτελεί κώδικα του ελεγκτή 45 lalis@inf.uth.gr
open call P3 46 lalis@inf.uth.gr
P3 open 47 lalis@inf.uth.gr
P3 open signal&block signal 48 lalis@inf.uth.gr
P3 open προσπεράστηκε από το P3 49 lalis@inf.uth.gr
P3 open exit 50 lalis@inf.uth.gr
P3 open 51 lalis@inf.uth.gr
open P3 52 lalis@inf.uth.gr
Συνθήκη ανταγωνισμού Ο μηχανισμός του ελεγκτή λύνει το πρόβλημα της συνθήκης ανταγωνισμού σε περίπτωση που ένα νήμα επιθυμεί να μπλοκάρει μέσα στον ελεγκτή Δεν υπάρχει περίπτωση να παρεμβληθεί άλλο νήμα ανάμεσα στον έλεγχο της συνθήκης αναμονής και την κλήση της wait Παρόλα αυτά, πάλι μπορεί να υπάρχουν συνθήκες ανταγωνισμού, ανάλογα με το μοντέλο προτεραιότητας της υλοποίησης του ελεγκτή Το eggshell-signal&block είναι ο πιο δίκαιος και διαισθητικά λογικός συνδυασμός (σειρά FIFO) 53 lalis@inf.uth.gr
Έλεγχος προδιαγραφών Αρκετές γλώσσες και περιβάλλοντα εκτέλεσης υποστηρίζουν μηχανισμούς συγχρονισμού που έχουν πολλές ομοιότητες με τον μηχανισμό του ελεγκτή Πριν αρχίσετε να γράφετε κώδικα, βεβαιωθείτε ότι γνωρίζετε ακριβώς ποιο μοντέλο ελεγκτή υλοποιούν Οι «μικρές» διαφορές ανάμεσα π.χ. σε eggshell/open σε συνδυασμό με signal&block/continue μπορεί να επηρεάσουν την ορθότητα του κώδικα Λύσεις που είναι σωστές με ένα μοντέλο δεν είναι απαραίτητα σωστές με ένα άλλο μοντέλο Στην συνέχεια υποθέτουμε eggshell-signal&block 54 lalis@inf.uth.gr