Sobes.tech
Middle+

O que é um livelock?

sobes.tech IA

Resposta da IA

Livelock é um estado semelhante ao deadlock, mas em vez de bloquear os threads, estes tentam constantemente realizar trabalho, cancelando mutuamente as ações devido à concorrência por recursos, o que impede o seu progresso.

Exemplo de livelock: dois threads tentam obter dois recursos A e B. Thread 1:

  1. Obtém o recurso A.
  2. Tenta obter o recurso B. Se não conseguir, liberta A e começa de novo.

Thread 2:

  1. Obtém o recurso B.
  2. Tenta obter o recurso A. Se não conseguir, liberta B e começa de novo.

Como resultado, os threads podem libertar constantemente os recursos e tentar obtê-los novamente, sem atingir um objetivo.

Diferenças com deadlock:

  • Deadlock: os threads estão bloqueados, esperando uns pelos outros.
  • Livelock: os threads trabalham ativamente, mas não progridem.

Prevenção:

  • Acesso ordenado aos recursos.
  • Tempos limite ao tentar obter um recurso.
  • Evitar dependências complexas entre recursos.

Exemplo de pseudocódigo com tentativa de livelock:

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

// Thread 1
DispatchQueue.global().async {
    while true {
        resource1.lock()
        if resource2.tryLock() {
            // Recursos obtidos com sucesso
            // Realizar trabalho
            print("Thread 1 realiza trabalho")
            resource2.unlock()
            resource1.unlock()
            break // Termina o ciclo após sucesso
        } else {
            // Não conseguiu obter resource2, libertar resource1 e tentar novamente
            resource1.unlock()
            // Pequena pausa para evitar tentativas imediatas
            Thread.sleep(forTimeInterval: 0.01)
        }
    }
}

// Thread 2
DispatchQueue.global().async {
    while true {
        resource2.lock()
        if resource1.tryLock() {
            // Recursos obtidos com sucesso
            // Realizar trabalho
            print("Thread 2 realiza trabalho")
            resource1.unlock()
            resource2.unlock()
            break // Termina o ciclo após sucesso
        } else {
            // Não conseguiu obter resource1, libertar resource2 e tentar novamente
            resource2.unlock()
            // Pequena pausa
            Thread.sleep(forTimeInterval: 0.01)
        }
    }
}