Sobes.tech
Middle+

Cos'è un livelock?

sobes.tech AI

Risposta dell'AI

Il livelock è uno stato simile al deadlock, ma invece di bloccare i thread, questi tentano costantemente di svolgere il lavoro, annullando le azioni reciproche a causa della competizione per le risorse, il che porta alla loro incapacità di progredire.

Esempio di livelock: due thread cercano di ottenere due risorse A e B. Thread 1:

  1. Ottiene la risorsa A.
  2. Cerca di ottenere la risorsa B. Se non riesce, rilascia A e ricomincia.

Thread 2:

  1. Ottiene la risorsa B.
  2. Cerca di ottenere la risorsa A. Se non riesce, rilascia B e ricomincia.

Di conseguenza, i thread possono continuamente rilasciare le risorse e tentare di ottenerle di nuovo, senza raggiungere un obiettivo.

Differenze con deadlock:

  • Deadlock: i thread sono bloccati, aspettando gli uni gli altri.
  • Livelock: i thread lavorano attivamente, ma non progrediscono.

Prevenzione:

  • Accesso ordinato alle risorse.
  • Timeout nel tentativo di ottenere una risorsa.
  • Evitare dipendenze complesse tra risorse.

Esempio di pseudocodice con tentativo di livelock:

// Risorsa 1
let resource1 = NSLock()
// Risorsa 2
let resource2 = NSLock()

// Thread 1
DispatchQueue.global().async {
    while true {
        resource1.lock()
        if resource2.tryLock() {
            // Entrambe le risorse ottenute con successo
            // Eseguire il lavoro
            print("Thread 1 esegue il lavoro")
            resource2.unlock()
            resource1.unlock()
            break // Termina il ciclo dopo il successo
        } else {
            // Non è stato possibile ottenere resource2, rilascia resource1 e riprova
            resource1.unlock()
            // Piccola pausa per evitare tentativi immediati
            Thread.sleep(forTimeInterval: 0.01)
        }
    }
}

// Thread 2
DispatchQueue.global().async {
    while true {
        resource2.lock()
        if resource1.tryLock() {
            // Entrambe le risorse ottenute con successo
            // Eseguire il lavoro
            print("Thread 2 esegue il lavoro")
            resource1.unlock()
            resource2.unlock()
            break // Termina il ciclo dopo il successo
        } else {
            // Non è stato possibile ottenere resource1, rilascia resource2 e riprova
            resource2.unlock()
            // Piccola pausa
            Thread.sleep(forTimeInterval: 0.01)
        }
    }
}