Προβλήματα Συγχρονισμού (με ελεγκτή) Ταυτόχρονος Προγραμματισμός 1

Σχετικά έγγραφα
Προβλήματα Συγχρονισμού (με ελεγκτή) Ταυτόχρονος Προγραμματισμός 1

Ελεγκτές/Παρακολουθητές (Monitors) Ταυτόχρονος Προγραμματισμός 1

Κλασικά Προβλήματα Συγχρονισμού (με σηματοφόρους) Ταυτόχρονος Προγραμματισμός 1

Κρίσιμη Περιοχή Υπό Συνθήκη (Conditional Critical Regions) Ταυτόχρονος Προγραμματισμός 1

Ελεγκτές/Παρακολουθητές (Monitors) Ταυτόχρονος Προγραμματισμός 1

Σηματοφόροι (Σηματοφορείς) Ταυτόχρονος Προγραμματισμός 1

Υλοποίηση Σηματοφόρων

Σηματοφόροι (Σηματοφορείς) Ταυτόχρονος Προγραμματισμός 1

2.4 Κλασσικά Προβλήματα IPC

Dr. Garmpis Aristogiannis - EPDO TEI Messolonghi

Αμοιβαίος αποκλεισμός με κοινή μνήμη. Ταυτόχρονος Προγραμματισμός 1

Αμοιβαίος αποκλεισμός με κοινή μνήμη. Ταυτόχρονος Προγραμματισμός 1

Λειτουργικά Συστήματα (ΗΥ222)

Συγχρονισμός & σηματοφόροι. Προγραμματισμός II 1

Λειτουργικά Συστήματα Η/Υ

Παράλληλη Επεξεργασία

Αμοιβαίος αποκλεισμός με κοινή μνήμη. Ταυτόχρονος Προγραμματισμός 1

Σύγχρονη επικοινωνία με ανταλλαγή μηνυμάτων (CSP message passing model) Ταυτόχρονος Προγραμματισμός 1

Χώροι Πλειάδων (Tuple Spaces) Ταυτόχρονος Προγραμματισμός 1

Χώροι Πλειάδων (Tuple Spaces) Ταυτόχρονος Προγραμματισμός 1

Λειτουργικά Συστήματα

Εργαστήριο 14. Συγχρονισμός Νημάτων (χρήση pthread_mutex_t, pthread_cond_t)

Ορθότητα λειτουργίας τμημάτων λογισμικού & δομών δεδομένων υπό ταυτόχρονη εκτέλεση

Λειτουργικά Συστήματα

Προσπέλαση σύνθετων δομών δεδομένων χωρίς καθολικό κλείδωμα

Όταν το πρόγραμμα φτάσει σε αυτή την εντολή και ο καταχωρητής PINA έχει την τιμή

Προσπέλαση σύνθετων δομών δεδομένων χωρίς καθολικό κλείδωμα

Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

Ορθότητα λειτουργίας τμημάτων λογισμικού & δομών δεδομένων υπό ταυτόχρονη εκτέλεση

Εικονική Μνήμη (Virtual Memory) Προγραμματισμός II 1

Εισαγωγή στα Λειτουργικά Συστήματα

Σύγχρονη επικοινωνία με ανταλλαγή μηνυμάτων (CSP message passing model) Ταυτόχρονος Προγραμματισμός 1

Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη)

Νήµαταστην Java. Συγχρονισµός νηµάτων Επικοινωνία νηµάτων Εκτελέσιµα αντικείµενα Νήµατα δαίµονες Οµάδες νηµάτων. Κατανεµηµένα Συστήµατα 11-1

Γιατί υϖάρχει τέτοια καθολική κατάσταση;

Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη)

Παράλληλη Επεξεργασία

Προγραμματισμός Ι (ΗΥ120)

Λειτουργικά Συστήματα. Ενότητα # 2: Διεργασίες και Νήματα Διδάσκων: Γεώργιος Ξυλωμένος Τμήμα: Πληροφορικής

Συστηματικός έλεγχος ορθότητας ταυτόχρονων προγραμμάτων μέσω γράφου καταστάσεων

Εισαγωγικά & Βασικές Έννοιες

Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη)

Επικοινωνία µεταξύ ιεργασιών και Σύνδροµες ιεργασίες

Λειτουργικά Συστήματα. Ενότητα # 2: Διεργασίες και Νήματα Διδάσκων: Γεώργιος Ξυλωμένος Τμήμα: Πληροφορικής

ΕΝΟΤΗΤΑ 4 Λήψη Αποφάσεων και Συναρτήσεις Ελέγχου

Αμοιβαίος αποκλεισμός με ασύγχρονη επικοινωνία (ανταλλαγή μηνυμάτων) Ταυτόχρονος Προγραμματισμός 1

ΠΛΗ111. Ανοιξη Μάθηµα 5 ο. Ουρά. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης

Κλείδωμα αρχείων (file locking) Προγραμματισμός II 1

Εικονική Μνήμη (Virtual Memory) Προγραμματισμός II 1

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

Εισαγωγικά & Βασικές Έννοιες

Συστηματικός έλεγχος ορθότητας ταυτόχρονων προγραμμάτων μέσω γράφου καταστάσεων

Βασικές Έννοιες Πρ Ταο υγρ τόα χ μ ρ μ ο α ν τισμ ος Π ό ρ ςο ΙΙΙ γραμματισμός 1

Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη)

Ορισµός Νήµα (thread) είναι µια ακολουθιακή ροή ελέγχου (δηλ. κάτι που έχει αρχή, ακολουθία εντολών και τέλος) σ ένα

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ II. Υφαντόπουλος Νικόλαος Υποψήφιος Διδάκτορας Contact:

Εισαγωγή στον Προγραμματισμό

Αγωγοί/Σωλήνες (Pipes) Προγραμματισμός II 1

Διεργασίες (μοντέλο μνήμης & εκτέλεσης) Προγραμματισμός II 1

Διεργασίες (Processes)

Προγραμματισμός Ταυτόχρονος Προγραμματισμός

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Εισαγωγή στη Java II

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ Ι ΙΕΡΓΑΣΙΕΣ ΕΙΣΑΓΩΓΗ ΣΤΙΣ ΙΕΡΓΑΣΙΕΣ

6. Αδιέξοδο. 1. Ορισμοί είδη πόρων. 3. Συνθήκες αδιεξόδου. 1. Πρόληψη 2. Αποφυγή 3. Ανίχνευση 5. Το πρόβλημα των συνδαιτημόνων φιλοσόφων

Αξιόπιστη μεταφορά δεδομένων πάνω από αναξιόπιστο δίκτυο. Κατανεμημένα Συστήματα 1

Αξιόπιστη μεταφορά δεδομένων πάνω από αναξιόπιστο δίκτυο. Κατανεμημένα Συστήματα 1

Δομές ελέγχου ροής προγράμματος

Δομές Δεδομένων & Αλγόριθμοι

Προγραμματισμός Ι (HY120)

Συλλογές, Στοίβες και Ουρές

Ανάπτυξη και Σχεδίαση Λογισμικού

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Εισαγωγή στη Java

Ουρές Μηνυμάτων (Message Queues in System V) Προγραμματισμός II 1

Συγχρονισμός Μέρος Α : Κρίσιμο τμήμα και κλειδώματα

Λειτουργικά Συστήματα Η/Υ

Εργαστήριο Λειτουργικών Συστημάτων 8ο εξάμηνο, Ακαδημαϊκή περίοδος

Κλείδωμα αρχείων (file locking) Προγραμματισμός II 1

Κατανεμημένα Συστήματα: Θεωρία και Προγραμματισμός. Ενότητα # 8: Ταυτοχρονισμός και νήματα Διδάσκων: Γεώργιος Ξυλωμένος Τμήμα: Πληροφορικής

Πανεπιστήμιο Πειραιώς Σχολή Τεχνολογιών Πληροφορικής και Επικοινωνιών Τμήμα Ψηφιακών Συστημάτων ομές εδομένων

Πανεπιστήμιο Πειραιώς Σχολή Τεχνολογιών Πληροφορικής και Επικοινωνιών Τμήμα Ψηφιακών Συστημάτων ομές εδομένων

Λειτουργικά Συστήματα. Ενότητα # 6: Αδιέξοδα Διδάσκων: Γεώργιος Ξυλωμένος Τμήμα: Πληροφορικής

Διεργασίες (μοντέλο μνήμης & εκτέλεσης) Προγραμματισμός II 1

ΔΙΕΡΓΑΣΙΕΣ. Λειτουργικά Συστήματα Ι. Διδάσκων: Καθ. Κ. Λαμπρινουδάκης ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ Ι

Εργαστήριο ΔΙΕΡΓΑΣΙΕΣ - ΔΙΑΧΕΙΡΙΣΗ

Δομημένος Προγραμματισμός

Εισαγωγή στην πληροφορική

Διασυνδεδεμένες Δομές. Δυαδικά Δέντρα. Προγραμματισμός II 1

Διαδιεργασιακή επικοινωνία (inter-process communication IPC) Προγραμματισμός II 1

Δυναμική δέσμευση και αποδέσμευση μνήμης. Προγραμματισμός II 1

Λειτουργικά Συστήματα 7ο εξάμηνο, Ακαδημαϊκή περίοδος

Δομές Δεδομένων. Ενότητα 4: Ο ΑΤΔ Λίστα & Υλοποίηση Λίστας με σειριακή αποθήκευση- Ο ΑΤΔ Συνδεδεμένη Λίστα- Υλοποίηση ΑΤΔ Συνδεδεμένη Λίστα με πίνακα

Παράλληλη Επεξεργασία Κεφάλαιο 4 Επικοινωνία Διεργασιών

Κατανεμημένα Συστήματα

Προγραμματισμός Ι (ΗΥ120)

Δομές Δεδομένων. Ενότητα 10: Πλήρη Δυαδικά Δέντρα, Μέγιστα/Ελάχιστα Δέντρα & Εισαγωγή στο Σωρό- Ο ΑΤΔ Μέγιστος Σωρός. Καθηγήτρια Μαρία Σατρατζέμη

Δείκτες σε συναρτήσεις. Προγραμματισμός II 1

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

Τμήμα Οικιακής Οικονομίας και Οικολογίας. Οργάνωση Υπολογιστών

Transcript:

Προβλήματα Συγχρονισμού (με ελεγκτή) Ταυτόχρονος Προγραμματισμός 1 lalis@inf.uth.gr

Υλοποίηση σηματοφόρων Οι σηματοφόροι είναι ένας ΑΤΔ με συγκεκριμένες λειτουργίες πρόσβασης Μπορεί να υλοποιηθούν με «φυσικό» τρόπο χρησιμοποιώντας τον μηχανισμό του ελεγκτή Ο αμοιβαίος αποκλεισμός κατά την πρόσβαση του εσωτερικού μετρητή επιτυγχάνεται αυτόματα, λόγω του μηχανισμού του ελεγκτή Το πρόβλημα που πρέπει να λυθεί είναι η αναμονή μέσα στην down, και αφύπνιση μέσω της up Χρησιμοποιούμε μια μεταβλητή συνθήκης Ταυτόχρονος Προγραμματισμός 2 lalis@inf.uth.gr

monitor binsem { bit val; /* τιμή σηματοφόρου */ condition q; /* ουρά αναμονής */ void init(bit v) { val = v; void down() { if (val == 0) { wait(q); val = 0; void up() { val = 1; signal(q); Ταυτόχρονος Προγραμματισμός 3 lalis@inf.uth.gr

monitor binsem { bit val; /* τιμή σηματοφόρου */ condition q; /* ουρά αναμονής */ void init(bit v) { val = v; είναι σωστό για μοντέλο open; void down() { if (val == 0) { wait(q); val = 0; void up() { val = 1; signal(q); Ταυτόχρονος Προγραμματισμός 4 lalis@inf.uth.gr

monitor binsem { bit val; /* τιμή σηματοφόρου */ condition q; /* ουρά αναμονής */ void init(bit v) { val = v; είναι σωστό για μοντέλο open; void down() { while (val == 0) { wait(q); val = 0; void up() { val = 1; signal(q); Ταυτόχρονος Προγραμματισμός 5 lalis@inf.uth.gr

monitor binsem { int val; /* τιμή σηματοφόρου */ condition q; /* ουρά αναμονής */ void init(int v) { val = v; τεχνική «κοιμώμενου κουρέα» void down() { val--; if (val < 0) { wait(q); void up() { if (val < 1) { val++; if (val <= 0) { signal(q); Ταυτόχρονος Προγραμματισμός 6 lalis@inf.uth.gr

Παραγωγός-καταναλωτής Το κλασικό πρόβλημα του παραγωγού-καταναλωτή με αποθήκη απεριόριστης χωρητικότητας Ο καταναλωτής πρέπει να μπλοκάρεται όταν επιχειρεί να απομακρύνει ένα κομμάτι από άδεια αποθήκη Και να αφυπνίζεται όταν τοποθετηθούν νέα κομμάτια Υλοποιούμε την αποθήκη ως ΑΔΤ σε ελεγκτή Η αναμονή/αφύπνιση καταναλωτών επιτυγχάνεται (α) μετρώντας τον αριθμό των κομματιών στην αποθήκη, και (β) χρησιμοποιώντας μια μεταβλητή συνθήκης Ταυτόχρονος Προγραμματισμός 7 lalis@inf.uth.gr

monitor buf { void init(); void put(data d); Data get(); Producer: while (1) {... /* produce Data item d */ put(d); Consumer: while (1) {... d=get(); /* consume Data item d */...... Ταυτόχρονος Προγραμματισμός 8 lalis@inf.uth.gr

monitor buf {... /* μεταβλητές αποθήκης */ int avl; /* # γεμάτων θέσεων */ condition notempty; /* αναμονή καταναλωτή */ void init() {... /* αρχικοποίηση αποθήκης */ avl = 0; void put(data d) {... /* τοποθέτηση στοιχείου στην αποθήκη */ avl++; if (avl == 1) { signal(notempty); Data get() { if (avl == 0) { wait(notempty); avl--;... /* απομάκρυση στοιχείου από την αποθήκη */ return(...); Ταυτόχρονος Προγραμματισμός 9 lalis@inf.uth.gr

monitor buf {... /* μεταβλητές αποθήκης */ int avl; /* # γεμάτων θέσεων */ condition notempty; /* αναμονή καταναλωτή */ void init() {... /* αρχικοποίηση αποθήκης */ avl = 0; είναι σωστό για μοντέλο open; void put(data d) {... /* τοποθέτηση στοιχείου στην αποθήκη */ avl++; if (avl == 1) { signal(notempty); Data get() { if (avl == 0) { wait(notempty); avl--;... /* απομάκρυση στοιχείου από την αποθήκη */ return(...); Ταυτόχρονος Προγραμματισμός 10 lalis@inf.uth.gr

Πρόβλημα με μοντέλο open Ο καταναλωτής ελέγχει την αποθήκη και μπλοκάρει αν αυτή είναι άδεια μια μοναδική φορά Όμως, όταν καλείται η signal, ο έλεγχος δεν δίνεται απαραίτητα στον καταναλωτή που περίμενε Μπορεί να δοθεί σε έναν άλλο καταναλωτή, που έχει μπλοκάρει προσπαθώντας να καλέσει την get, και έτσι να προσπεραστεί ο πρώτος καταναλωτής Η συνθήκη αφύπνισης μπορεί να ακυρωθεί Η συνθήκη αναμονής πρέπει να ελέγχεται ξανά, αφού ο καταναλωτής εκτελέσει / βγει από την wait Ταυτόχρονος Προγραμματισμός 11 lalis@inf.uth.gr

monitor buf {... /* μεταβλητές αποθήκης */ int avl; /* # γεμάτων θέσεων */ condition notempty; /* αναμονή καταναλωτή */ void init() {... /* αρχικοποίηση αποθήκης */ avl = 0; είναι σωστό για μοντέλο open; void put(data *d) {... /* τοποθέτηση στοιχείου στην αποθήκη */ avl++; if (avl == 1) { signal(notempty); Data *get() { while (avl == 0) { wait(notempty); avl--;... /* απομάκρυνση στοιχείου από την αποθήκη */ return(...); Ταυτόχρονος Προγραμματισμός 12 lalis@inf.uth.gr

Πρόβλημα με μοντέλο open Δεν γνωρίζουμε πότε ακριβώς πρέπει να αφυπνιστεί ένας καταναλωτής μέσω signal(notempty) Η συνθήκη αφύπνισης δεν είναι απαραίτητα σωστή Γιατί; Ως συνέπεια, υπάρχει περίπτωση να μην κληθεί πότε signal(notempty) παρότι κάποιος καταναλωτής έχει μπλοκάρει και η αποθήκη δεν είναι άδεια Ταυτόχρονος Προγραμματισμός 13 lalis@inf.uth.gr

monitor buf {... /* μεταβλητές αποθήκης */ int avl; /* # γεμάτων θέσεων */ condition notempty; /* αναμονή καταναλωτή */ void init() {... /* αρχικοποίηση αποθήκης */ avl = 0; void put(data *d) {... /* τοποθέτηση στοιχείου στην αποθήκη */ avl++; signal(notempty); /* σε κάθε περίπτωση */ Data *get() { while (avl == 0) { wait(notempty); avl--;... /* απομάκρυνση στοιχείου από την αποθήκη */ return(...); Ταυτόχρονος Προγραμματισμός 14 lalis@inf.uth.gr

Πρόβλημα με μοντέλο open Υπάρχει ακόμα πρόβλημα λιμοκτονίας, καθώς ένας καταναλωτής που περιμένει μπορεί να προσπερνιέται συνεχώς από νέους καταναλωτές Λύση: τεχνική κοιμώμενου κουρέα Ταυτόχρονος Προγραμματισμός 15 lalis@inf.uth.gr

monitor buf {... /* μεταβλητές αποθήκης */ int avl; /* # γεμάτων θέσεων */ condition notempty; /* αναμονή καταναλωτή */ void init() {... /* αρχικοποίηση αποθήκης */ avl = 0; void put(data *d) {... /* τοποθέτηση στοιχείου στην αποθήκη */ avl++; if (avl <= 0) { signal(notempty); Data *get() { avl--; if (avl < 0) { wait(notempty);... /* απομάκρυνση στοιχείου από την αποθήκη */ return(...); Ταυτόχρονος Προγραμματισμός 16 lalis@inf.uth.gr

Παραγωγός-καταναλωτής με αποθήκη περιορισμένης χωρητικότητας Η σχέση αναμονής/αφύπνισης είναι συμμετρική ανάμεσα στους καταναλωτές και τους παραγωγούς Ότι κάναμε για την αναμονή των καταναλωτών (σε άδεια αποθήκη) και την αφύπνιση τους από τους παραγωγούς, το ίδιο πρέπει να γίνει και για την αναμονή παραγωγών (σε γεμάτη αποθήκη) και την αφύπνιση τους από τους καταναλωτές Στο ίδιο πνεύμα με την προηγούμενη λύση Ταυτόχρονος Προγραμματισμός 17 lalis@inf.uth.gr

monitor buf {... /* μεταβλητές αποθήκης */ int free,full; /* # άδειων/γεμάτων θέσεων */ condition notfull,notempty; /* αναμονή παρ. & κατ. */ void init() {... /* αρχικοποίηση αποθήκης */ free = N; full = 0; void put(data *d) { if (free == 0) { wait(notfull); free--;... /* τοποθέτηση στοιχείου στην αποθήκη */ full++; if (full == 1) { signal(notempty); Data *get() { Data *d; if (full == 0) { wait(notempty); full--;... /* απομάκρυση στοιχείου από την αποθήκη */ free++; if (free == 1) { signal(notfull); return(...); Ταυτόχρονος Προγραμματισμός 18 lalis@inf.uth.gr

monitor buf {... /* μεταβλητές αποθήκης */ int free,full; /* # άδειων/γεμάτων θέσεων */ condition notfull,notempty; /* αναμονή παρ. & κατ. */ void init() {... /* αρχικοποίηση αποθήκης */ free = N; full = 0; void put(data *d) { free--; if (free < 0) { wait(notfull);... /* τοποθέτηση στοιχείου στην αποθήκη */ full++; if (full <= 0) { signal(notempty); Data *get() { Data *d; full--; if (full < 0) { wait(notempty);... /* απομάκρυση στοιχείου από την αποθήκη */ free++; if (free <= 0) { signal(notfull); return(...); Ταυτόχρονος Προγραμματισμός 19 lalis@inf.uth.gr

Αναγνώστες και εγγραφείς ιδέα Κώδικας εισόδου/εξόδου μέσα σε ελεγκτή, με ξεχωριστές ουρές αναμονής (μεταβλητές συνθήκης) Είσοδος αναγνώστη: αν υπάρχει στο ΚΤ εγγραφέας, περίμενε στην ουρά των αναγνωστών Είσοδος εγγραφέα: αν υπάρχει στο ΚΤ αναγνώστης ή εγγραφέας, περίμενε στην ουρά των εγγραφέων Έξοδος τελευταίου αναγνώστη: ξύπνα τον επόμενο εγγραφέα, αν υπάρχει Έξοδος εγγραφέα: ξύπνα τον/τους επόμενο/ους αναγνώστη/ες, αν υπάρχουν, διαφορετικά τον επόμενο εγγραφέα, αν υπάρχει Ταυτόχρονος Προγραμματισμός 20 lalis@inf.uth.gr

monitor rwsync { void init(); void startread(); void stopread(); void startwrite(); void stopwrite(); Reader: while (1) { startread(); /* read */ stopread(); Writer: while (1) { startwrite(); /* write */ stopwrite(); Ταυτόχρονος Προγραμματισμός 21 lalis@inf.uth.gr

monitor rwsync { int rds,wrs; /* #αναγνωστών/εγγραφέων στο ΚΤ */ condition rq,wq; /* ουρές αναμονής */ int rcnt, wcnt; /* #νημάτων μπλοκαρισμένα σε rq/wq */ void init() { rds = 0; wrs = 0; rcnt = 0; wcnt =0; void startread(); void stopread(); void startwrite(); void stopwrite(); Ταυτόχρονος Προγραμματισμός 22 lalis@inf.uth.gr

void startread() { if (wrs > 0) { rcnt++; wait(rq); rds++; void stopread() { rds--; if ((rds == 0) && (wcnt > 0)) { wcnt--; signal(wq); void startwrite() { if ((wrs > 0) (rds > 0)) { wcnt++; wait(wq); wrs++; void stopwrite() { wrs--; if (rcnt > 0) { do { rcnt--; signal(rq); while (rcnt > 0); else if (wcnt > 0) { wcnt--; signal(wq); Ταυτόχρονος Προγραμματισμός 23 lalis@inf.uth.gr

void startread() { if (wrs > 0) { rcnt++; wait(rq); if (rcnt > 0) { rcnt--; signal(rq); rds++; void stopread() { rds--; if ((rds == 0) && (wcnt > 0)) { wcnt--; signal(wq); void startwrite() { if ((wrs > 0) (rds > 0)) { wcnt++; wait(wq); wrs++; void stopwrite() { wrs--; if (rcnt > 0) { rcnt--; signal(rq); else if (wcnt > 0) { wcnt--; signal(wq); Ταυτόχρονος Προγραμματισμός 24 lalis@inf.uth.gr

Λιμοκτονία εγγραφέων Ένας νέος αναγνώστης θα προσπεράσει έναν εγγραφέα που περιμένει, αν στο ΚΤ υπάρχουν ήδη και άλλοι αναγνώστες Αυτό μπορεί να συνεχίζεται απ άπειρο Πιο δίκαιο: ένας νέος αναγνώστης πρέπει να περιμένει αν ήδη περιμένει ένας εγγραφέας Με ελεγκτή (σε αντίθεση με τους σηματοφόρους), αυτό είναι εύκολο να επιτευχθεί, με μια απλή επέκταση της υπάρχουσας λύσης Ταυτόχρονος Προγραμματισμός 25 lalis@inf.uth.gr

void startread() { if ((wrs > 0) (wcnt > 0)) { rcnt++; wait(rq); if (rcnt > 0) { rcnt--; signal(rq); rds++; void stopread() { rds--; if ((rds == 0) && (wcnt > 0)) { wcnt--; signal(wq); void startwrite() { if ((wrs > 0) (rds > 0)) { wcnt++; wait(wq); wrs++; void stopwrite() { wrs--; if (rcnt > 0) { rcnt--; signal(rq); else if (wcnt > 0) { wcnt--; signal(wq); Ταυτόχρονος Προγραμματισμός 26 lalis@inf.uth.gr

Προσπεράσματα Πάλι μπορεί να προσπεραστεί ένας εγγραφέας Όταν εξέρχεται ένας εγγραφέας από το ΚΤ, δίνει προτεραιότητα στους αναγνώστες, που με την σειρά τους αφυπνίζονται όλοι Όμως, δεν μπορεί να υπάρξει λιμοκτονία Γιατί; Ανάποδα, η προτεραιότητα εισόδου μπορεί να δοθεί στους εγγραφείς τότε όμως πάλι υπάρχει περίπτωση λιμοκτονίας για τους αναγνώστες Ταυτόχρονος Προγραμματισμός 27 lalis@inf.uth.gr

Συνδαιτημόνες φιλόσοφοι ιδέα Υλοποιούμε τη ρουτίνα getforks(i) μέσω της οποίας ο i-οστός φιλόσοφος επιχειρεί να πιάσει τα πιρούνια που βρίσκονται δεξιά και αριστερά του Υλοποιούμε τη ρουτίνα putforks(i) μέσω της οποίας ο i-οστός φιλόσοφος αφήνει τα πιρούνια του Χρησιμοποιούμε ένα πίνακα avl[ν] που καταγράφει τα διαθέσιμα πιρούνια για κάθε φιλόσοφο (0, 1, 2) Χρησιμοποιούμε ένα πίνακα caneat[ν] από μεταβλητές συνθήκης, μια για κάθε φιλόσοφο Ταυτόχρονος Προγραμματισμός 28 lalis@inf.uth.gr

monitor table { Pi: while (1) { /* think */ void init(); void getforks(int i); void putforks (int i); getforks(i); /* eat */ putforks(i); Ταυτόχρονος Προγραμματισμός 29 lalis@inf.uth.gr

monitor dining_philosophers { int avl[n]; condition caneat[ν]; void init() { int i; for (i=0; i<ν; i++) { avl[i] = 2; void getforks(int i) { if (avl[i]!= 2) { wait(caneat[i]); avl[right(i)]--; avl[left(i)]--; void putforks(int i) { avl[right(i)]++; if (avl[right(i)] == 2) { signal(caneat[right(i)]); avl[left(i)]++; if (avl[left(i)] == 2) { signal(caneat[left(i)]); Ταυτόχρονος Προγραμματισμός 30 lalis@inf.uth.gr

Παρατηρήσεις Ο αμοιβαίος αποκλεισμός είναι εγγυημένος Δεν υπάρχει περίπτωση αδιεξόδου, και πάντα κάποιος φιλόσοφος θα καταφέρνει να τρώει Υπάρχει όμως περίπτωση λιμοκτονίας Ένας φιλόσοφος δεν θα καταφέρει να φάει ποτέ, αν οι γείτονες του τρώνε συντονισμένα εναλλάξ έτσι ώστε ποτέ να μην είναι ταυτόχρονα διαθέσιμα τόσο το δεξί όσο και το αριστερό πιρούνι του Υπάρχει θέμα signal-block ή signal-continue; Είναι η λύση σωστή για μοντέλο open; Ταυτόχρονος Προγραμματισμός 31 lalis@inf.uth.gr

Υλοποίηση ελεγκτή με σηματοφόρους (eggshell/signal-block) Ταυτόχρονος Προγραμματισμός 32 lalis@inf.uth.gr

Πρόβλημα Έστω ότι μας δίνονται σηματοφόροι Μπορούμε να πετύχουμε λειτουργικότητα συγχρονισμού στο πνεύμα ενός ελεγκτή; Ζητούμενο 1 ο : Πως επιτυγχάνεται το πλαίσιο του αμοιβαίου αποκλεισμού; Ζητούμενο 2 ο : Πως υλοποιείται μια μεταβλητή συνθήκης, καθώς και οι λειτουργίες wait / signal; Ταυτόχρονος Προγραμματισμός 33 lalis@inf.uth.gr

Eggshell mtx ουρά εισόδου x_q ουρά νημάτων που έχουν καλέσει την wait στη μεταβλητή συνθήκης x s_q νήμα που εκτελεί κώδικα του ελεγκτή ουρά νημάτων που περιμένουν (λόγω κλήσης της signal) να ελευθερωθεί ο ελεγκτής Ταυτόχρονος Προγραμματισμός 34 lalis@inf.uth.gr

Μεταβλητές πλαισίου συγχρονισμού Σηματοφόρος για αμοιβαίο αποκλεισμό: bsem mtx; /* αμοιβαίος αποκλεισμός */ init(&mtx,1); Για κάθε μεταβλητή συνθήκης x, σηματοφόρος και μετρητής για την υλοποίηση της ουράς αναμονής: bsem x_q; /* ουρά μεταβλητής συνθήκης */ int x_n=0; /* # νημάτων στην ουρά */ init(&x_q,0); x_n = 0; Σηματοφόρος και μετρητής για τις διεργασίες που μπλοκάρουν λόγω κλήσης της signal: bsem s_q; /* ουρά για signal */ int s_n; /* # νημάτων στην ουρά */ init(&s_q,0); s_n = 0; Ταυτόχρονος Προγραμματισμός 35 lalis@inf.uth.gr

void proc( ) { down(mtx); /* συμβατικός κώδικας της ρουτίνας */ if (s_n > 0) { s_n--; up(s_q); else { up(mtx); void wait(condition x) { x_n++; if (s_n > 0) { s_n--; up(s_q); else { up(mtx); down(x_q); void signal(condition x) { if (x_n > 0) { s_n++; x_n--; up(x_q); down(s_q); Ταυτόχρονος Προγραμματισμός 36 lalis@inf.uth.gr

Μια λύση αποκλειστικά για signal&exit Έστω ότι η signal καλείται μόνο ως τελευταία εντολή μιας λειτουργίας του ελεγκτή (ή τερματίζει άμεσα την λειτουργία, στο πνεύμα της exit/return) Τότε δεν χρειάζεται να μπλοκάρει το νήμα που καλεί την signal δεν τίθεται θέμα αμοιβαίου αποκλεισμού αφού το νήμα στην συνέχεια θα εγκαταλείψει τον ελεγκτή Συνεπώς δεν χρειάζεται η ουρά που υλοποιείται μέσω του σηματοφόρου s_q και μετρητή s_n Ταυτόχρονος Προγραμματισμός 37 lalis@inf.uth.gr

void proc( ) { down(mtx); /* */ up(mtx); void wait(condition x) { x_n++; up(mtx); down(x_q); void signal(condition x) { if (x_n > 0) { x_n--; up(x_q); else { up(mtx); Ταυτόχρονος Προγραμματισμός 38 lalis@inf.uth.gr