Sobes.tech
Middle+

Šta je livelock?

sobes.tech АИ

Одговор од АИ

Livelock — тоје стање слично dead-lock-у, али уместо блокирања, течејеви се стално покушавају обавити посао, отказујући једни друге због конкуренције за ресурсе, што доводи до њихове неспособности да напредују.

Пример livelock-а: два тока покушавају да узму два ресурса A и B. Ток 1:

  1. Добија ресурс A.
  2. Покушава да добије ресурс B. Ако не успе, ослобађа A и почиње изнова.

Ток 2:

  1. Добија ресурс B.
  2. Покушава да добије ресурс A. Ако не успе, ослобађа B и почиње изнова.

Као резултат, токови могу стално да ослобађају ресурсе и покушавају поново да их добију, без постизања циља.

Разлике од dead-lock-а:

  • Dead-lock: токови су блокирани, чекајући једни друге.
  • 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()
            // Мали одмор да избегнемо тренутни поновни покушај,
            // али то не гарантује избегавање livelock-а
            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)
        }
    }
}