Condição de Corrida (Race Condition)

Definição

Condição de Corrida (Race Condition) é uma falha que ocorre quando duas ou mais threads ou processos acessam e manipulam recursos compartilhados ao mesmo tempo, de forma não controlada. Isso pode levar a resultados incorretos, imprevisíveis ou inconsistentes, pois a ordem de execução influencia diretamente o comportamento do programa.

Situações de condição de corrida geralmente ocorrem quando múltiplas unidades de execução:

  • Lêem e escrevem na mesma variável;
  • Não utilizam mecanismos de sincronização (como locks ou semáforos);
  • Dependem da ordem de execução para funcionar corretamente.

Condições de corrida nem sempre ocorrem em todas as execuções — isso torna o bug ainda mais perigoso e difícil de identificar em testes.

Por que a Condição de Corrida é um problema

  • Identificar situações perigosas em sistemas concorrentes.
  • Evitar falhas sutis e intermitentes que surgem apenas em determinadas condições de execução.
  • Promover o uso de boas práticas de sincronização e controle de acesso a recursos compartilhados.

Exemplo prático (com condição de corrida)

Este código simula duas threads modificando a mesma variável contador, sem proteção:

import threading

contador = 0

def incrementar():
    global contador
    for _ in range(100000):
        contador += 1

t1 = threading.Thread(target=incrementar)
t2 = threading.Thread(target=incrementar)

t1.start()
t2.start()

t1.join()
t2.join()

print("Valor final:", contador)

Saída esperada

Valor final: 200000 # (esperado)

Saída real (exemplo de condição de corrida)

Valor final: 182391 # ou outro valor incorreto

O valor final geralmente será menor que 200000, pois as threads podem sobrescrever os valores entre si — um clássico exemplo de condição de corrida.

O ciclo da Condição de Corrida

[Thread A lê contador = 10]
[Thread B lê contador = 10]
[Thread A escreve contador = 11]
[Thread B escreve contador = 11] <-- sobrescreve valor anterior
  • As leituras e escritas ocorrem sem coordenação.
  • Resultado: atualizações se perdem.

Como evitar

Use um lock (trava) para garantir que apenas uma thread modifique a variável por vez:

import threading

contador = 0
lock = threading.Lock()

def incrementar():
    global contador
    for _ in range(100000):
        with lock:
            contador += 1

Com o uso de with lock, o acesso ao contador torna-se exclusivo por thread, evitando interferências.

Relacionados

Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com