Sobes.tech
Middle+

Τι είναι ένα livelock;

sobes.tech AI

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

Livelock — κατάσταση που μοιάζει με deadlock, αλλά αντί να μπλοκάρουν τα νήματα, αυτά προσπαθούν συνεχώς να εκτελέσουν εργασία, ακυρώνοντας αμοιβαία τις ενέργειες τους λόγω ανταγωνισμού για πόρους, οδηγώντας στην αδυναμία προόδου.

Παράδειγμα livelock: δύο νήματα προσπαθούν να αποκτήσουν δύο πόρους A και B. Νήμα 1:

  1. Αποκτά τον πόρο A.
  2. Προσπαθεί να αποκτήσει τον πόρο B. Αν αποτύχει, απελευθερώνει τον A και ξεκινά ξανά.

Νήμα 2:

  1. Αποκτά τον πόρο B.
  2. Προσπαθεί να αποκτήσει τον πόρο A. Αν αποτύχει, απελευθερώνει τον B και ξεκινά ξανά.

Ως αποτέλεσμα, τα νήματα μπορούν συνεχώς να απελευθερώνουν πόρους και να προσπαθούν ξανά να τους αποκτήσουν, χωρίς να επιτυγχάνουν τον στόχο.

Διαφορές με deadlock:

  • Deadlock: τα νήματα είναι μπλοκαρισμένα, περιμένοντας το ένα το άλλο.
  • Livelock: τα νήματα εργάζονται ενεργά, αλλά δεν προχωρούν.

Πρόληψη:

  • Ταξινομημένη πρόσβαση στους πόρους.
  • Χρονικά όρια κατά την προσπάθεια απόκτησης πόρου.
  • Αποφυγή πολύπλοκων εξαρτήσεων μεταξύ πόρων.

Παράδειγμα ψευδοκώδικα με προσπάθεια livelock:

// Πόρος 1
let resource1 = NSLock()
// Πόρος 2
let resource2 = NSLock()

// Νήμα 1
DispatchQueue.global().async {
    while true {
        resource1.lock()
        if resource2.tryLock() {
            // Και οι δύο πόροι αποκτήθηκαν με επιτυχία
            // Εκτέλεση εργασίας
            print("Νήμα 1 εκτελεί εργασία")
            resource2.unlock()
            resource1.unlock()
            break // Τερματισμός μετά την επιτυχία
        } else {
            // Δεν κατάφερε να αποκτήσει τον resource2, απελευθερώνει τον resource1 και προσπαθεί ξανά
            resource1.unlock()
            // Μικρή καθυστέρηση για να αποφευχθούν άμεσες επαναλήψεις
            Thread.sleep(forTimeInterval: 0.01)
        }
    }
}

// Νήμα 2
DispatchQueue.global().async {
    while true {
        resource2.lock()
        if resource1.tryLock() {
            // Και οι δύο πόροι αποκτήθηκαν με επιτυχία
            // Εκτέλεση εργασίας
            print("Νήμα 2 εκτελεί εργασία")
            resource1.unlock()
            resource2.unlock()
            break // Τερματισμός μετά την επιτυχία
        } else {
            // Δεν κατάφερε να αποκτήσει τον resource1, απελευθερώνει τον resource2 και προσπαθεί ξανά
            resource2.unlock()
            // Μικρή καθυστέρηση
            Thread.sleep(forTimeInterval: 0.01)
        }
    }
}