Sobes.tech
Middle+

Čo je to livelock?

sobes.tech AI

Odpoveď od AI

Livelock — je stav, podoben dead-lock-u, ale namiesto blokovania, vlákna sa neustále snažia vykonať prácu, zrušením akcií navzájom kvôli konkurencii o zdroje, čo vedie k ich neschopnosti posunúť sa vpred.

Príklad livelock-u: dve vlákna sa snažia získať dva zdroje A a B. Vlákno 1:

  1. Získa zdroj A.
  2. Snaží sa získať zdroj B. Ak sa mu to nepodarí, uvoľní A a začína znova.

Vlákno 2:

  1. Získa zdroj B.
  2. Snaží sa získať zdroj A. Ak sa mu to nepodarí, uvoľní B a začína znova.

Výsledkom je, že vlákna môžu neustále uvoľňovať zdroje a znova sa snažiť ich získať, nedosiahnuc cieľa.

Rozdiely od dead-lock-u:

  • Dead-lock: vlákna sú zablokované, čakajúc na seba.
  • Livelock: vlákna aktívne pracujú, ale nepridávajú na postupe.

Prevencia:

  • Usporiadaný prístup k zdrojom.
  • Časové limity pri pokuse o získanie zdroja.
  • Vyhýbanie sa zložitým závislostiam medzi zdrojmi.

Príklad pseudokódu s pokusom o livelock:

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

// Vlákno 1
DispatchQueue.global().async {
    while true {
        resource1.lock()
        if resource2.tryLock() {
            // Úspešne získané oba zdroje
            // Vykonávame prácu
            print("Vlákno 1 vykonáva prácu")
            resource2.unlock()
            resource1.unlock()
            break // Ukončenie cyklu po úspešnom získaní
        } else {
            // Nepodarilo sa získať resource2, uvoľníme resource1 a skúšame znova
            resource1.unlock()
            // Malé zdržanie, aby sa predišlo livelocku
            Thread.sleep(forTimeInterval: 0.01)
        }
    }
}

// Vlákno 2
DispatchQueue.global().async {
    while true {
        resource2.lock()
        if resource1.tryLock() {
            // Úspešne získané oba zdroje
            // Vykonávame prácu
            print("Vlákno 2 vykonáva prácu")
            resource1.unlock()
            resource2.unlock()
            break // Ukončenie cyklu po úspešnom získaní
        } else {
            // Nepodarilo sa získať resource1, uvoľníme resource2 a skúšame znova
            resource2.unlock()
            // Malé zdržanie
            Thread.sleep(forTimeInterval: 0.01)
        }
    }
}