Pular para o conteúdo

Impasse

Duas threads, duas travas, em ordens diferentes: cada uma segura o que a outra espera. A ordem fixa, e o prazo.

A thread 1 toma a trava do estoque e espera a do caixa; a thread 2 tomou a do caixa e espera a do estoque. As duas ficam paradas para sempre, vivas e caladas — é o impasse (deadlock). O processo não cai, não levanta, não escreve no log: simplesmente para de responder.

A cura: sempre a mesma ordem#

O impasse precisa de duas threads pedindo travas em ordens diferentes. Se toda thread toma as travas na mesma ordem — por exemplo, sempre a do estoque antes da do caixa —, o ciclo não tem como se formar:

dataforge
adopt Arcane.Concurrent as P

estoque := P.mutex()
caixa := P.mutex()
vendas := []

// A regra do programa: estoque ANTES de caixa, em todo lugar
action vender(item):
    P.com_trava(estoque, lambda => P.com_trava(caixa, lambda => vendas.append(item)))

parallel:
    vender("café")
    vender("chá")
assert len(vendas) is 2

O prazo, para não travar calado#

dataforge
adopt Arcane.Concurrent as P

esgotou := no
monitor:
    P.com_prazo(lambda => sleep(500), 0.05)       // quem chama não fica preso
handle Error as e:
    esgotou := yes
assert esgotou

Com um ator não há travas para ordenar, e com STM o conflito vira nova tentativa — as duas formas evitam o impasse por construção.