Seção Crítica
Definição
Seção Crítica (ou região crítica) é qualquer trecho de código que acessa recursos compartilhados (como variáveis globais, arquivos ou conexões) de forma que apenas uma thread ou processo pode executá-lo por vez sem causar comportamentos incorretos.
O nome “crítica” vem do fato de que a concorrência descontrolada nesse ponto pode comprometer o funcionamento do programa, causando condições de corrida, dados corrompidos ou falhas difíceis de rastrear.
Objetivos do conceito de Seção Crítica
- Delimitar trechos sensíveis que exigem exclusão mútua durante execução concorrente.
- Prevenir condições de corrida e inconsistência de dados.
- Facilitar a aplicação de mecanismos de sincronização, como locks, semáforos e monitores.
- Tornar o código concorrente mais seguro e previsível.
Exemplo prático (Python)
Neste exemplo, a variável saldo
é acessada por duas threads que representam depósitos em uma conta. O acesso ao saldo
é protegido por um lock
:
import threading
saldo = 0
lock = threading.Lock()
def depositar(valor):
global saldo
for _ in range(100000):
with lock:
saldo += valor # <- Seção crítica
t1 = threading.Thread(target=depositar, args=(1,))
t2 = threading.Thread(target=depositar, args=(1,))
t1.start()
t2.start()
t1.join()
t2.join()
print("Saldo final:", saldo)
Saída esperada
Saldo final: 200000
Sem o lock
, essa mesma operação provavelmente resultaria em um valor incorreto — um clássico sintoma de condição de corrida na seção crítica.
O ciclo da Seção Crítica
[Thread A entra] --> executa operação crítica --> sai
[Thread B entra] --> executa operação crítica --> sai
Apenas uma thread pode acessar a seção por vez.
As outras devem aguardar a liberação do recurso.
Como identificar uma seção crítica
Você está lidando com uma seção crítica quando:
Há concorrência (várias threads/processos atuando ao mesmo tempo).
Um trecho de código lê ou altera um recurso compartilhado.
O comportamento do programa varia dependendo da ordem de execução.
ℹ️ Ao identificar seções críticas, aplique mecanismos de sincronização apenas onde for necessário — proteger código demais pode levar a bloqueios desnecessários e perda de performance