Sobes.tech
Middle

Ποια είναι η διαφορά μεταξύ ενός σερφω και ενός mutex;

sobes.tech AI

Απάντηση από AI

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

Ένα mutex (αμοιβαία αποκλεισμός) είναι ένας δυαδικός σημαφόρος που μπορεί να βρίσκεται είτε σε κατάσταση μπλοκαρίσματος είτε σε κατάσταση απελευθέρωσης. Χρησιμοποιείται για την προστασία κρίσιμων τμημάτων κώδικα από ταυτόχρονη πρόσβαση από πολλά νήματα. Μόνο ένα νήμα μπορεί να αποκτήσει το mutex σε μια δεδομένη στιγμή. Το νήμα που έχει αποκτήσει το mutex δεν μπορεί να διακοπεί από ένα άλλο νήμα που προσπαθεί να το αποκτήσει. Αν προσπαθήσετε να αποκτήσετε ένα μπλοκαρισμένο mutex, το νήμα θα μπλοκαριστεί μέχρι να απελευθερωθεί.

Βασικές διαφορές:

Χαρακτηριστικό Σημαφόρος Mutex
Τύπος Γενικευμένος μηχανισμός συγχρονισμού Δυαδικός σημαφόρος (ειδική περίπτωση σημαφόρου)
Τιμή Ακέραιος (>= 0) Δυαδικός (0 ή 1)
Σκοπός Έλεγχος πρόσβασης σε πόρους, περιορισμός νημάτων Προστασία κρίσιμων τμημάτων, αμοιβαία αποκλεισμός
Ιδιοκτήτης Μπορεί να μην έχει ιδιοκτήτη Πάντα έχει ιδιοκτήτη (το νήμα που τον απέκτησε)
Χρήση σε iOS DispatchSemaphore Συχνά υλοποιείται μέσω DispatchQueue.sync ή NSRecursiveLock σε ορισμένα σενάρια

Παράδειγμα χρήσης mutex για την προστασία κρίσιμης ενότητας:

// Στο πλαίσιο του GCD (Grand Central Dispatch)
let serialQueue = DispatchQueue(label: "com.example.criticalSection")

serialQueue.sync {
    // Κρίσιμη ενότητα κώδικα
    // Μόνο ένα νήμα μπορεί να είναι εδώ κάθε στιγμή
}

Παράδειγμα χρήσης σημαφόρου για τον περιορισμό παράλληλων εργασιών:

// Στο πλαίσιο του GCD (Grand Central Dispatch)
let semaphore = DispatchSemaphore(value: 3) // Επιτρέπει 3 παράλληλες εργασίες

DispatchQueue.global().async {
    semaphore.wait() // Μειώνει την τιμή του σημαφόρου κατά 1. Μπλοκάρει αν η τιμή είναι 0.

    // Κώδικας παράλληλης εργασίας
    print("Εργασία σε εξέλιξη")

    Thread.sleep(forTimeInterval: 1) // Προσομοίωση εργασίας

    semaphore.signal() // Αυξάνει την τιμή του σημαφόρου κατά 1. Ξεκλειδώνει το αναμένον νήμα, αν υπάρχει.
    print("Εργασία ολοκληρώθηκε")
}

// Μπορούν να ξεκινήσουν πολλά τέτοια μπλοκ. Μόνο 3 θα εκτελεστούν ταυτόχρονα.