Middle+
Ce este un livelock?
sobes.tech AI
Răspuns de la AI
Livelock este o stare similară cu deadlock, dar în loc ca firele de execuție să fie blocate, acestea încearcă constant să îndeplinească munca, anulând reciproc acțiunile din cauza concurenței pentru resurse, ceea ce duce la incapacitatea lor de a avansa.
Exemplu de livelock: două fire de execuție încearcă să obțină două resurse A și B. Firea 1:
- Obține resursa A.
- Încearcă să obțină resursa B. Dacă nu reușește, eliberează A și începe din nou.
Firea 2:
- Obține resursa B.
- Încearcă să obțină resursa A. Dacă nu reușește, eliberează B și începe din nou.
Ca rezultat, firele pot elibera constant resursele și pot încerca să le obțină din nou, fără a atinge un scop.
Diferențe față de deadlock:
- Deadlock: firele sunt blocate, așteptând unul pe celălalt.
- Livelock: firele lucrează activ, dar nu progresează.
Prevenție:
- Acces ordonat la resurse.
- Timeout-uri la încercarea de a obține o resursă.
- Evitarea dependențelor complexe între resurse.
Exemplu de pseudocod cu încercare de livelock:
// Resursa 1
let resource1 = NSLock()
// Resursa 2
let resource2 = NSLock()
// Firea 1
DispatchQueue.global().async {
while true {
resource1.lock()
if resource2.tryLock() {
// Ambele resurse au fost obținute cu succes
// Executarea muncii
print("Firea 1 execută munca")
resource2.unlock()
resource1.unlock()
break // Încheierea ciclului după succes
} else {
// Nu s-a putut obține resource2, eliberează resource1 și încearcă din nou
resource1.unlock()
// Pauză scurtă pentru a evita încercările imediate
Thread.sleep(forTimeInterval: 0.01)
}
}
}
// Firea 2
DispatchQueue.global().async {
while true {
resource2.lock()
if resource1.tryLock() {
// Ambele resurse au fost obținute cu succes
// Executarea muncii
print("Firea 2 execută munca")
resource1.unlock()
resource2.unlock()
break // Încheierea ciclului după succes
} else {
// Nu s-a putut obține resource1, eliberează resource2 și încearcă din nou
resource2.unlock()
// Pauză scurtă
Thread.sleep(forTimeInterval: 0.01)
}
}
}