Skip to content
Latchkey

O que é uma Race Condition? Quando o timing muda o resultado

Uma race condition é um bug em que o resultado de um programa depende da ordem ou do timing imprevisível de operações concorrentes, em vez de depender apenas da lógica.

Quando dois ou mais threads ou processos tocam estado compartilhado ao mesmo tempo, a ordem em que rodam pode mudar o resultado. Se o programa assume uma ordenação mas outra pode acontecer, isso é uma race condition. Races são notórias porque são intermitentes: o mesmo código pode passar mil vezes e falhar na milésima primeira.

Como uma race acontece

Imagine dois threads lendo um contador, somando um e escrevendo de volta. Se eles se intercalam de certa forma, ambos leem o mesmo valor inicial e uma atualização se perde. O bug não está em nenhum dos threads isoladamente; está no acesso não sincronizado ao estado compartilhado.

Por que races são tão difíceis

  • São dependentes de timing, então aparecem e somem de forma imprevisível.
  • Muitas vezes só aparecem sob carga ou em máquinas mais rápidas ou mais lentas.
  • Podem passar localmente e falhar no CI, ou vice-versa.
  • Reproduzi-las de forma confiável é difícil, o que atrasa a depuração.

Como prevenir races

Coordene o acesso a estado compartilhado com locks, operações atômicas ou construções de mais alto nível como filas e dados imutáveis. A correção mais segura muitas vezes é evitar compartilhar estado mutável por completo, passando dados em vez de mutá-los no lugar.

Races vs deadlocks

Uma race condition é coordenação de menos: os threads pisam uns nos outros. Um deadlock é coordenação demais: os threads esperam uns pelos outros para sempre. Ambos vêm de concorrência, mas são modos de falha opostos.

Um exemplo rápido

Dois testes que escrevem no mesmo arquivo temporário sem isolamento podem competir: dependendo do escalonamento, um sobrescreve o outro, e qual deles falha muda de execução para execução.

Race conditions no CI

Races são uma das principais causas de testes flaky: uma suíte passa em um laptop rápido mas falha de forma intermitente em runners de CI ocupados, onde o timing muda. A correção é remover a race, não dar retry, embora a Latchkey possa dar retry automático nas execuções enquanto você isola a causa real, para que uma única falha flaky não bloqueie um merge.

Principais conclusões

  • Uma race condition faz o resultado depender do timing concorrente imprevisível.
  • Races vêm de acesso não sincronizado a estado mutável compartilhado.
  • São uma das principais causas de testes flaky no CI e devem ser corrigidas, não apenas ter retry.

Guias relacionados