Concorrência (Concurrency)
Definição
Concorrência (Concurrency) é a capacidade de um programa lidar com múltiplas tarefas em execução de forma intercalada, sem necessariamente executá-las ao mesmo tempo.
Ou seja, uma aplicação concorrente pode alternar entre diferentes tarefas para melhorar eficiência, responsividade ou uso de recursos — mesmo em computadores que executam apenas uma tarefa por vez (como aqueles com um único núcleo de CPU).
Concorrência não significa execução simultânea real (isso é paralelismo), mas sim a estruturação do programa para lidar com várias tarefas em progresso, alternando entre elas de maneira controlada.
Objetivos da Concorrência
- Melhorar a responsividade de sistemas interativos (como interfaces gráficas ou servidores).
- Executar tarefas que não dependem uma da outra enquanto aguarda, por exemplo, a resposta de uma API ou do disco.
- Aproveitar o tempo ocioso de forma eficiente, evitando bloqueios desnecessários.
- Facilitar o controle de múltiplas tarefas menores, em vez de lidar com um único fluxo grande e complexo.
- Evitar bloqueios globais: o sistema pode continuar executando partes do programa mesmo se uma tarefa estiver aguardando.
Exemplo prático
Neste exemplo, usamos concorrência assíncrona com asyncio
para simular duas tarefas que alternam entre si durante a execução.
import asyncio
async def tarefa(nome, tempo):
for i in range(3):
print(f'{nome} - passo {i}')
await asyncio.sleep(tempo)
async def main():
# Executa duas tarefas de forma concorrente
await asyncio.gather(
tarefa("Tarefa A", 1),
tarefa("Tarefa B", 0.5)
)
asyncio.run(main())
Saída esperada
Tarefa A - passo 0
Tarefa B - passo 0
Tarefa B - passo 1
Tarefa A - passo 1
Tarefa B - passo 2
Tarefa A - passo 2
Observe que as tarefas se alternam: enquanto uma "espera", a outra avança.
O ciclo da concorrência
Abaixo está uma representação passo a passo do comportamento intercalado entre tarefas concorrentes:
[Tarefa A: passo 0] -> espera 1s
[Tarefa B: passo 0] -> espera 0.5s
[Tarefa B: passo 1] -> espera 0.5s
[Tarefa A: passo 1] -> espera 1s
[Tarefa B: passo 2] -> espera 0.5s
[Tarefa A: passo 2] -> fim
- As tarefas compartilham o tempo de execução, intercalando suas ações.
- O sistema gerencia qual tarefa está ativa com base nos pontos de espera (
await
). - Em Python, isso pode ser feito com
asyncio
(concorrência cooperativa) outhreading
(concorrência baseada em threads).
Em
asyncio
, as tarefas não rodam ao mesmo tempo, mas são pausadas e retomadas em pontos de espera — ideal para operações de I/O (rede, disco, etc.).