Sobes.tech
Middle+

Kas yra livelock?

sobes.tech AI

Atsakymas iš AI

Livelock — tai būklė, panaši į dead-lock, tačiau vietoj blokavimo, srautai nuolat bando atlikti darbą, atšaukdami vieni kitų veiksmus dėl išteklių konkurencijos, kas lemia jų nesugebėjimą žengti pirmyn.

Livelock pavyzdys: du srautai bando gauti du išteklius A ir B. Srautas 1:

  1. Gaukia išteklių A.
  2. Bando gauti išteklių B. Jei nepavyksta, atlaisvina A ir pradeda iš naujo.

Srautas 2:

  1. Gaukia išteklių B.
  2. Bando gauti išteklių A. Jei nepavyksta, atlaisvina B ir pradeda iš naujo.

Dėl to srautai gali nuolat atlaisvinti išteklius ir bandyti juos vėl gauti, nepasiekdami tikslo.

Skirtumai nuo dead-lock:

  • Dead-lock: srautai yra užblokuoti, laukia vieni kitų.
  • Livelock: srautai aktyviai dirba, bet nepraprogressuoja.

Prevencija:

  • Tvarkingas prieigos prie išteklių tvarkymas.
  • Laiko limitai bandant gauti išteklius.
  • Sudėtingų priklausomybių tarp išteklių vengimas.

Pavyzdinis pseudokodas su bandymu sukelti livelock:

// Išteklis 1
let resource1 = NSLock()
// Išteklis 2
let resource2 = NSLock()

// Srautas 1
DispatchQueue.global().async {
    while true {
        resource1.lock()
        if resource2.tryLock() {
            // Sėkmingai gauti abu išteklius
            // Atlikti darbą
            print("Srautas 1 atlieka darbą")
            resource2.unlock()
            resource1.unlock()
            break // Baigti ciklą po sėkmingo gavimo
        } else {
            // Nepavyko gauti resource2, atlaisvinti resource1 ir bandyti iš naujo
            resource1.unlock()
            // Nedidelis laukimas, siekiant išvengti livelock
            Thread.sleep(forTimeInterval: 0.01)
        }
    }
}

// Srautas 2
DispatchQueue.global().async {
    while true {
        resource2.lock()
        if resource1.tryLock() {
            // Sėkmingai gauti abu išteklius
            // Atlikti darbą
            print("Srautas 2 atlieka darbą")
            resource1.unlock()
            resource2.unlock()
            break // Baigti ciklą po sėkmingo gavimo
        } else {
            // Nepavyko gauti resource1, atlaisvinti resource2 ir bandyti iš naujo
            resource2.unlock()
            // Nedidelis laukimas
            Thread.sleep(forTimeInterval: 0.01)
        }
    }
}