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

Σχετικά έγγραφα
Συγχρονισμός. Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων

Συγχρονισμός. Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων

Συγχρονισμός. Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων

Dr. Garmpis Aristogiannis - EPDO TEI Messolonghi

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

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

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

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

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

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

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

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

Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων. Συγχρονισμός

Μηχανισμοί και προγραμματιστικές δομές συγχρονισμού. Προβλήματα συγχρονισμού (και λύσεις)

Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων. Συγχρονισμός

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

ΚΕΦΑΛΑΙΟ 9. Ταυτόχρονος προγραμματισμός και νήματα. 9.1 Εισαγωγή

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

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

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

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

Παρουσίαση 5 ης Άσκησης:

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

3 η ΑΣΚΗΣΗ. Προηγμένα Θέματα Αρχιτεκτονικής Υπολογιστών

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

Παρουσίαση 5 ης Άσκησης:

Parallel Architectures

Αμοιβαίος αποκλεισμός

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

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

ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ ΣΧΟΛΗ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ ΥΠΟΛΟΓΙΣΤΩΝ ΤΟΜΕΑΣ ΤΕΧΝΟΛΟΓΙΑΣ ΠΛΗΡΟΦΟΡΙΚΗΣ ΚΑΙ ΥΠΟΛΟΓΙΣΤΩΝ

Συγχρονισμός. Συστήματα Παράλληλης Επεξεργασίας 9ο εξάμηνο ΣΗΜΜΥ ακ. έτος CSLab. Κορνήλιος Κούρτης

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

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

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

ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ ΣΧΟΛΗ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ ΥΠΟΛΟΓΙΣΤΩΝ ΤΟΜΕΑΣ ΤΕΧΝΟΛΟΓΙΑΣ ΠΛΗΡΟΦΟΡΙΚΗΣ ΚΑΙ ΥΠΟΛΟΓΙΣΤΩΝ

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

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

Υ- 07 Παράλληλα Συστήματα Συνέπεια και συνοχή μνήμης

ΣυγχρονισµόςσεΣυστήµατα ΠολλαπλώνΝηµάτων

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

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ ΔΙΑΔΙΕΡΓΑΣΙΑΚΗ ΕΠΙΚΟΙΝΩΝΙΑ ΣΥΓΧΡΟΝΙΣΜΟΣ

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

Καρακασίδης Αλέξανδρος Καστίδου Γεωργία Παπαφώτη Μαρία Πέτσιος Κων/νος Στέφανος Σαλτέας Καλογεράς Παναγιώτης. Threads in Java ΝΗΜΑΤΑ ΣΤΗ JAVA

HY-486 Αρχές Κατανεμημένου Υπολογισμού Εαρινό Εξάμηνο

Διεργασίες και Νήματα (2/2)

CSLab National Technical University of Athens

Διάλεξη 9: Αλγόριθμοι Αμοιβαίου Αποκλεισμού με τη χρήση μεταβλητών Ανάγνωσης/Εγγραφής. ΕΠΛ 432: Κατανεμημένοι Αλγόριθμοι

Διάλεξη 10: Αλγόριθμοι Αμοιβαίου Αποκλεισμού σε περιβάλλον ανταλλαγής μηνυμάτων. ΕΠΛ 432: Κατανεμημένοι Αλγόριθμοι

Θοδωρής Ανδρόνικος Τμήμα Πληροφορικής, Ιόνιο Πανεπιστήμιο

Διάλεξη Εισαγωγή στη Java, Μέρος Γ

Parallel Architectures

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

Το μάθημα. Λειτουργικά Συστήματα Πραγματικού Χρόνου Βασικές Έννοιες 6. Ενσωματωμένα Συστήματα (embedded systems) Παραδείγματα

Ποια ιδιότητα αϖό τις δύο τελευταίες είναι ϖιο ισχυρή;

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

ΠΛΗΡΟΦΟΡΙΚΗ Ι JAVA Τμήμα θεωρίας με Α.Μ. σε 3, 7, 8 & 9 22/11/07

Parallel Architectures

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

Μάθημα 4 ο. Κρίσιμα Τμήματα και Αμοιβαίος Αποκλεισμός

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

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

Λειτουργικά Συστήματα Πραγματικού Χρόνου

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

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

ΠΛΕ- 074 Αρχιτεκτονική Υπολογιστών 2

Προγραμματισμός με Κοινόχρηστο Χώρο Διευθύνσεων 4

Αντικειμενοστρεφής Προγραμματισμός

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ

Μεταγλωττιστές Βελτιστοποίηση

ΕΘΝΙΚΟ ΚΑΙ ΚΑΠΟΔΙΣΤΡΙΑΚΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΑΘΗΝΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ & ΤΗΛΕΠΙΚΟΙΝΩΝΙΩΝ ΧΕΙΜΕΡΙΝΟ ΕΞΑΜΗΝΟ ΜΑΘΗΜΑ: ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ

Τ.Ε.Ι. Μεσολογγίου, Τµήµα τηλεπικοινωνιακών Συστημάτων & Δικτύων

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

Συνέπεια μνήμης σε πολυπύρηνα/πολυεπεξεργαστικά συστήματα

Πληροφορική ΙΙ Θεματική Ενότητα 5

Προσπέλαση κοινών πόρων Πρωτόκολλα ελέγχου αμοιβαίου αποκλεισμού

Μεταγλωττιστές Βελτιστοποίηση

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

Διάλεξη 8: Πρόβλημα Αμοιβαίου Αποκλεισμού. ΕΠΛ 432: Κατανεμημένοι Αλγόριθμοι

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

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

Ενότητα 4 (Κεφάλαιο 5) Συντρέχων Προγραμματισμός

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

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

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

Παράλληλος προγραμματισμός: Σχεδίαση παράλληλων προγραμμάτων

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

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

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

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

Προγραμματισμός και Χρήση Ηλεκτρονικών Υπολογιστών - Βασικά Εργαλεία Λογισμικού

Υ- 07 Παράλληλα Συστήματα Transac9onal memory

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

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

Υ- 07 Παράλληλα Συστήματα Συνχρονισμός, κρυφές μνήμες πολλαπλών επιπέδων

Παράλληλη Επεξεργασία Κεφάλαιο 5 Μοίρασμα Δεδομένων

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Μέθοδοι

Δομές Δεδομένων & Ανάλυση Αλγορίθμων. 3ο Εξάμηνο. Ουρά (Queue) Υλοποίηση της με τη βοήθεια πίνακα.

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα

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

Transcript:

Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων Συγχρονισμός Μέρος Α : Κρίσιμο τμήμα και κλειδώματα 9 ο Εξάμηνο

Η ανάγκη για συγχρονισμό Ταυτόχρονη πρόσβαση σε κοινά δεδομένα μπορεί να οδηγήσει σε ασυνεπή εκτέλεση Το πρόβλημα του κρίσιμου τμήματος (critical section): το πολύ μία διεργασία πρέπει να βρίσκεται στο κρίσιμο τμήμα σε κάθε χρονική στιγμή Δεν μας ενδιαφέρει η σειρά εκτέλεσης, αλλά η συντονισμένη πρόσβαση στα κοινά δεδομένα (ένας-ένας παιδιά! ) Η σωστή παράλληλη εκτέλεση απαιτεί συγκεκριμένη σειρά εκτέλεσης, όπως π.χ. επιβάλλεται από το γράφο εξαρτήσεων Το πρόβλημα της σειριοποίησης (ordering) Υπάρχει αυστηρά προκαθορισμένη σειρά με την οποία πρέπει να εκτελεστούν οι εργασίες

Άλλα patterns συγχρονισμού Φράγμα συγχρονισμού (barrier) Όλες οι διεργασίες που συμμετέχουν συγχρονίζονται σε ένα συγκεκριμένο σημείο κώδικα Ειδική περίπτωση της σειριοποίησης Αναγνώστες-εγγραφείς (readers writers) Στο «κρίσιμο τμήμα» επιτρέπεται να είναι είτε: Καμία διεργασία Οσεσδήποτε διεργασίες αναγνώστες Μία διεργασία εγγραφέας Παραγωγός-καταναλωτής (producer consumer) Φραγμένος αριθμός από προϊόντα (0 < items < N) Ο παραγωγός εισέρχεται στο «κρίσιμο τμήμα» όταν items < N Ο καταναλωτής εισέρχεται στο «κρίσιμο τμήμα» όταν items > 0 Χρειάζεται συγχρονισμένη πρόσβαση στη δομή που κρατάει τα προϊόντα αν items = (και συγχρονισμένη ενημέρωση του μετρητή items) 3

Μηχανισμοί συγχρονισμού Κλειδώματα (locks) Προστατεύει ένα τμήμα κώδικα από ταυτόχρονη πρόσβαση Μόνο η διεργασία που έχει λάβει το κλείδωμα μπορεί να προχωρήσει Σημαφόροι (semaphores) Ακέραιος αριθμός στον οποίο επιτρέπονται 3 ενέργειες Αρχικοποίηση Αύξηση της τιμής κατά Μείωση της τιμής κατά και μπλοκάρισμα αν η νέα τιμή είναι 0 (ή αρνητική ανάλογα με την υλοποίηση) Παρακολουθητές (monitors) και condition variables Ζεύγος κλειδώματος και condition variable (m, c) Μία διεργασία αναστέλλει τη λειτουργία της (λειτουργία wait) μέχρι να ισχύσει η κατάλληλη συνθήκη Μία διεργασία «ξυπνάει» (λειτουργία signal) κάποια από τις διεργασίες που περιμένουν 4

Το πρόβλημα του κρίσιμου τμήματος (και οι ιδιότητές του). Αμοιβαίος αποκλεισμός (mutual exclusion) 2. Πρόοδος (deadlock free) 3. Πεπερασμένη αναμονή (starvation free) Τα και 2 είναι αναγκαία, το 3 επιθυμητό

Το κλείδωμα ως λύση του κρίσιμου τμήματος do { lock(mylock); /* critical section */ code unlock(mylock); remainder section while (TRUE); do { lock(mylock); /* critical section */ other code unlock(mylock); other remainder section while (TRUE);

Το κλείδωμα ως λύση του κρίσιμου τμήματος do { lock(mylock); /* critical section */ code unlock(mylock); remainder section while (TRUE); do { lock(mylock); /* critical section */ other code unlock(mylock); other remainder section while (TRUE); Πώς υλοποιείται ένα σωστό και «καλό» κλείδωμα;

Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα // i = εγώ // j = το άλλο νήμα public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {; public void unlock() { flag[i] = ;

Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα // i = εγώ «Θέλω να μπω» // j = το άλλο νήμα public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {; public void unlock() { flag[i] = ;

Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα // i = εγώ «Θέλω να μπω» // j = το άλλο νήμα public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {; public void unlock() { flag[i] = ; Παραχώρηση προτεραιότητας «Μπες εσύ»

Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα // i = εγώ // j = το άλλο νήμα public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {; public void unlock() { flag[i] = ; «Θέλω να μπω» Παραχώρηση προτεραιότητας «Μπες εσύ» Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα

Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα Νήμα 2 «Θέλω να μπω» «Θέλω να μπω» «Μπες εσύ» «Μπες εσύ» χρόνος Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα

Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα Νήμα 2 «Θέλω να μπω» «Θέλω να μπω» «Μπες εσύ» «Μπες εσύ» χρόνος Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Μπαίνει στο κρίσιμο τμήμα Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Μπλοκάρει

Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα Νήμα 2 «Θέλω να μπω» «Θέλω να μπω» «Μπες εσύ» «Μπες εσύ» χρόνος Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Αν ο compiler ή ο επεξεργαστής αναδιατάξει την η εντολή: Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα

Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα Νήμα 2 «Θέλω να μπω» «Θέλω να μπω» «Μπες εσύ» «Μπες εσύ» χρόνος Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα

Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα Νήμα 2 «Μπες εσύ» «Θέλω να μπω» «Μπες εσύ» χρόνος Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα «Θέλω να μπω»

Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα Νήμα 2 «Μπες εσύ» «Θέλω να μπω» «Μπες εσύ» χρόνος Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Μπαίνει στο κρίσιμο τμήμα Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα «Θέλω να μπω» Μπαίνει στο κρίσιμο τμήμα

class Bakery { boolean[] flag; Label[] label; int size; Λύση στο λογισμικό: Lamport s Bakery Algorithm public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = ; label[i] = 0; public void lock() { int i = ThreadID.get(); flag[i] = true; label[i] = max(label[0],, label[n-]) + ; while ((Эk!= i)(flag[k] && (label[k],k) << label[i],i))) {; public void unlock() { flag[threadid.get()] = ;

class Bakery { boolean[] flag; Label[] label; int size; Λύση στο λογισμικό: Lamport s Bakery Algorithm «Θέλω να μπω» public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = ; label[i] = 0; public void lock() { int i = ThreadID.get(); flag[i] = true; label[i] = max(label[0],, label[n-]) + ; while ((Эk!= i)(flag[k] && (label[k],k) << label[i],i))) {; public void unlock() { flag[threadid.get()] = ;

class Bakery { boolean[] flag; Label[] label; int size; public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = ; label[i] = 0; Λύση στο λογισμικό: Lamport s Bakery Algorithm «Θέλω να μπω» Παίρνει σειρά προτεραιότητας public void lock() { int i = ThreadID.get(); flag[i] = true; label[i] = max(label[0],, label[n-]) + ; while ((Эk!= i)(flag[k] && (label[k],k) << label[i],i))) {; public void unlock() { flag[threadid.get()] = ;

class Bakery { boolean[] flag; Label[] label; int size; Λύση στο λογισμικό: Lamport s Bakery Algorithm «Θέλω να μπω» public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = ; label[i] = 0; public void lock() { int i = ThreadID.get(); flag[i] = true; label[i] = max(label[0],, label[n-]) + ; while ((Эk!= i)(flag[k] && (label[k],k) << label[i],i))) {; public void unlock() { flag[threadid.get()] = ; Παίρνει σειρά προτεραιότητας Αναμονή μέχρι να έρθει η προτεραιότητά μου Αν 2 νήματα έχουν αποκτήσει τον ίδιο αριθμό προτεραιότητας, λαμβάνεται υπόψη το id τους

class Bakery { boolean[] flag; Label[] label; int size; Λύση στο λογισμικό: Lamport s Bakery Algorithm public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = ; label[i] = 0; public void lock() { int i = ThreadID.get(); flag[i] = true; label[i] = max(label[0],, label[n-]) + ; while ((Эk!= i)(flag[k] && (label[k],k) << label[i],i))) {; «Δεν θέλω να μπω» public void unlock() { flag[threadid.get()] = ;

Ζητήματα λύσεων στο λογισμικό Βασίζονται σε απλές αναγνώσεις και εγγραφές στη μνήμη (+) Το κλείδωμα του Peterson: Λειτουργεί μόνο για 2 διεργασίες (-) Δεν λειτουργεί αν ο μεταγλωττιστής ή ο επεξεργαστής δεν αναδιατάξουν εντολές (-) Στο μεταγλωττιστή μπορώ να το επιβάλλω Στον επεξεργαστή χρειάζεται ειδική εντολή (memory fence) To κλείδωμα του Lamport Λειτουργεί για Ν διεργασίες (+) Διατρέχει Ν θέσεις μνήμης και αυτό μπορεί να είναι πολύ αργό και μη κλιμακώσιμο για μεγάλα Ν (-) 23

Υποστήριξη από το υλικό: atomic operations, π.χ. test-and-set, compare-and-swap Ατομικά ενεργούν σε 2 μεταβλητές 0 State Test (0 = unlocked = locked)

Υποστήριξη από το υλικό: atomic operations, π.χ. test-and-set, compare-and-swap Ατομικά ενεργούν σε 2 μεταβλητές 0 0 State Test (0 = unlocked = locked)

Υποστήριξη από το υλικό: atomic operations, π.χ. test-and-set, compare-and-swap Ατομικά ενεργούν σε 2 μεταβλητές Με ένα ατομικό operation θέτω το lock (State=) και «βλέπω» την προηγούμενη κατάσταση (στη μεταβλητή Test) 0 0 State Test (0 = unlocked = locked)

Υποστήριξη από το υλικό: atomic operations, π.χ. test-and-set, compare-and-swap Ατομικά ενεργούν σε 2 μεταβλητές Με ένα ατομικό operation θέτω το lock (State=) και «βλέπω» την προηγούμενη κατάσταση (στη μεταβλητή Test) 0 0 State (0 = unlocked = locked) Test Αν test = 0 (ήταν «ξεκλείδωτα») μπαίνω στο critical section, αλλιώς περιμένω

Test-and-set (TAS) lock class TASlock { AtomicBoolean state = new AtomicBoolean(); void lock() { while (state.getandset(true)) { void unlock() { state.set();

TAS lock in a bus-based multiprocessor Thread inside critical section CPU0 CPU CPU2 Memory state test cache 0 cache cache state test 0 bus

TAS lock in a bus-based multiprocessor Thread inside critical section CPU0 Thread 2 tries to enter critical section CPU while (state.getandset(true)) { Thread 3 tries to enter critical section CPU2 while (state.getandset(true)) { Memory state test cache 0 cache cache state test 0 bus

TAS lock in a bus-based multiprocessor Thread inside critical section CPU0 Thread 2 tries to enter critical section CPU while (state.getandset(true)) { Thread 3 tries to enter critical section CPU2 while (state.getandset(true)) { Memory state test cache state test cache state test cache state test bus

TAS lock in a bus-based multiprocessor Thread inside critical section CPU0 Thread 2 tries to enter critical section CPU while (state.getandset(true)) { Thread 3 tries to enter critical section CPU2 while (state.getandset(true)) { Memory state test cache state test cache state test cache state test bus Υπερβολική χρήση του διαδρόμου λόγω πρωτοκόλλου συνάφειας κρυφής μνήμης

Test and test and set (TTAS) lock class TTASlock { AtomicBoolean state = new AtomicBoolean(); void lock() { while (true) { while (state.get()) {; if (!state.getandset(true)) return; void unlock() { state.set();

Test and test and set (TTAS) lock class TTASlock { AtomicBoolean state = new AtomicBoolean(); «Επίμονο» διάβασμα της void lock() { κατάστασης του lock while (true) { while (state.get()) {; if (!state.getandset(true)) return; void unlock() { state.set();

Test and test and set (TTAS) lock class TTASlock { AtomicBoolean state = new AtomicBoolean(); «Επίμονο» διάβασμα της κατάστασης του lock void lock() { while (true) { while (state.get()) {; if (!state.getandset(true)) return; void unlock() { state.set(); Αν είναι «ξεκλείδωτο» το διεκδικώ

Επίδοση TAS vs TTAS TAS lock time TTAS lock Ideal threads

Επίδοση TAS vs TTAS TAS lock time TTAS lock Ideal threads Περαιτέρω βελτίωση: TTAS + εκθετική οπισθοχώρηση (exponential backoff)

Scalable locks Σε ένα σύστημα κοινής μνήμης δεν είναι καλή ιδέα πολλά threads να «συνωστίζονται» σε μία κοινή θέση μνήμης Δημιουργείται μεγάλη κυκλοφορία δεδομένων από το σύστημα συνάφειας κρυφής μνήμης Προτιμούμε τα νήματα να εργάζονται το καθένα στο δικό του χώρο και να έχουν πρόσβαση σε κοινές θέσεις σπάνια και με λογική point-to-point, π.χ. 2 νήματα ανά θέση μνήμης

Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = ; flag[(slot + ) % size] = true;

Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); Τοπική μεταβλητή ανά thread Πίνακας-ουρά με αριθμό θέσεων ίσο με τον αριθμό των threads Δείκτης στο τέλος της ουράς public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = ; flag[(slot + ) % size] = true;

Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = ; flag[(slot + ) % size] = true; 6 5 7 4 tail 0 true 3 0 2 Alock mylock = new Alock(8); /* Thread code */ mylock.lock(); /* critical section */ mylock.unlock();

Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); 6 5 7 4 tail 0 true 3 2 Thread A mylock.lock() public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = ; flag[(slot + ) % size] = true;

Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); 6 5 7 4 tail 2 0 true 3 2 Thread A in CS Thread B mylock.lock() public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = ; flag[(slot + ) % size] = true;

Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); 6 5 7 4 tail 3 0 true 3 2 Thread A in CS Thread B mylock.lock() Thread C mylock.lock() public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = ; flag[(slot + ) % size] = true;

Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); 6 5 7 4 tail 3 0 3 true 2 Thread A mylock.unlock() Thread B mylock.lock() Thread C mylock.lock() public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = ; flag[(slot + ) % size] = true;

Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); 6 5 7 4 tail 3 0 3 true 2 Thread B In CS Thread C mylock.lock() public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = ; flag[(slot + ) % size] = true;

Επισημάνσεις Η επίδοση κάθε μηχανισμού κλειδώματος εξαρτάται από τη συμφόρηση Αριθμός νημάτων Μέγεθος κρίσιμου τμήματος Μέγεθος μη-κρίσιμου τμήματος Δεν υπάρχει ένα κλείδωμα για όλες τις περιπτώσεις Υβριδικές προσεγγίσεις έχουν νόημα Οι παραπάνω υλοποιήσεις αφορούν spinlocks ο επεξεργαστής είναι κατειλημμένος όσο ένα νήμα επιχειρεί να εισέλθει στο κρίσιμο τμήμα Μπορούν να συνδυαστούν ορθογώνια με προσεγγίσεις όπου το νήμα απελευθερώνει τον επεξεργαστή μετά από κάποιο χρονικό διάστημα 47

The following joke circulated in Italy in the 920s. According to Mussolini, the ideal citizen is intelligent, honest, and Fascist. Unfortunately, no one is perfect, which explains why everyone you meet is either intelligent and Fascist but not honest, honest and Fascist but not intelligent, or honest and intelligent but not Fascist. The Art of Multiprocessor Programming By Maurice Herlihy, Nir Shavit 48