asyncio.Lock e Event: Sincronize Corrotinas resolve um problema recorrente em projetos Python: Proteja estado compartilhado entre tarefas e sinalize quando uma condição estiver pronta. Este guia mostra o mecanismo, um exemplo executável e os limites que evitam uma implementação frágil.

Conceito e caso de uso

Mesmo em um único event loop, uma corrotina pode pausar em await e permitir que outra observe estado intermediário. Lock serializa a seção crítica; Event difunde um sinal.

Para revisar os fundamentos relacionados, consulte também o guia de async e await. A integração fica mais simples quando cada função recebe dependências e dados explicitamente, em vez de depender de estado global.

Exemplo prático

import asyncio

lock = asyncio.Lock()
ready = asyncio.Event()
balance = 0

async def add(value: int) -> None:
    global balance
    async with lock:
        current = balance
        await asyncio.sleep(0)
        balance = current + value
    ready.set()

Mantenha a seção protegida pequena e use async with para liberar o lock em exceções. Estas primitivas não sincronizam threads.

Decisões importantes

A escolha correta depende do contrato público, do volume e do comportamento em caso de falha.

Considere como a solução se comporta sob concorrência, entradas vazias e falhas parciais. Documente qualquer limite que afete consumidores e mantenha nomes que expressem a intenção.

Erros comuns

O exemplo mínimo não substitui limites, tratamento de erros e observabilidade. Fazer I/O lento segurando o lock reduz concorrência e pode criar deadlock. Event não carrega dados e seu sinal permanece ativo até clear.

Evite capturar exceções sem contexto ou retornar resultados parciais como se fossem completos. Uma falha explícita costuma ser mais segura que dados silenciosamente incorretos.

Como validar

Valide o comportamento, não apenas a linha feliz. Force alternância com pontos de espera controlados, use timeout nos testes e confirme que exceções liberam o lock.

A documentação oficial, consultada em 28 de julho de 2026, detalha a API e deve ser a referência para mudanças futuras.