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 2O 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 esgotouCom 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.