
Passo 1 de 8
Concorrência não é o mesmo que paralelismo
Leia linhas do tempo para diferenciar sequência, concorrência e paralelismo.
Trilha de aprendizado · Nível 13 · Tutorial 1
Ao concluir, você será capaz de escolher um modelo de concorrência conforme o tipo de tarefa, as necessidades de compartilhamento de dados e as características do interpretador.
Concorrência não é o mesmo que paralelismo
Leia linhas do tempo para diferenciar sequência, concorrência e paralelismo. 2 min
Identificar o que limita a tarefa
Classifique tarefas pela etapa que mais domina sua duração: espera por recursos, processamento ou uma combinação dos dois. 2 min
Threads: execução com memória compartilhada
Entenda o que threads compartilham dentro de um processo e por que elas são uma opção para coordenar esperas de entrada e saída. 2 min
Processos: isolamento e comunicação explícita
Entenda como espaços de memória separados afetam o paralelismo, os dados e os custos de usar processos. 2 min
Asyncio: tarefas que cooperam no laço de eventos
Entenda como tarefas cooperam no laço de eventos e reconheça o que impede esse progresso. 2 min
Considerar o GIL e a configuração do interpretador
Entenda como o GIL e a configuração efetiva do interpretador afetam as expectativas sobre threads. 2 min
Transformar os critérios em uma escolha
Use uma sequência de decisão para selecionar uma estratégia inicial — ou decidir manter a execução sequencial — considerando gargalo, bibliotecas, estado e custos. 2 min
Aplicação final: justificar e revisar a decisão
Aplique os critérios de escolha a cenários concretos, explique os custos envolvidos e identifique quando uma decisão deve ser revista. 2 min

Passo 1 de 8
Leia linhas do tempo para diferenciar sequência, concorrência e paralelismo.
Em uma execução sequencial, a tarefa B só começa quando a tarefa A termina.
Há concorrência quando mais de uma tarefa faz progresso em períodos que se sobrepõem. Isso pode ocorrer por alternância: enquanto A aguarda algo, B executa.
Há paralelismo quando duas tarefas estão efetivamente executando ao mesmo tempo.
Observe que a sobreposição no tempo não significa, por si só, dois trechos executando no mesmo instante.

Azul e laranja representam tarefas; cinza representa espera. Só o último caso mostra execução simultânea.
Exemplo
Imagine duas tarefas: A consulta um serviço e B prepara um relatório.
Uma tarefa aguardando está pendente, mas não está executando processamento naquele momento.
Dica
A concorrência pode aproveitar períodos de espera, mas não garante que o tempo total será menor. Há custos de coordenação, e a tarefa pode não ter espera útil para sobrepor.
Qual linha do tempo representa concorrência, mas não paralelismo?

Passo 2 de 8
Classifique tarefas pela etapa que mais domina sua duração: espera por recursos, processamento ou uma combinação dos dois.
Uma tarefa é limitada por entrada e saída (I/O-bound) quando passa a maior parte do tempo aguardando recursos externos, como rede, banco de dados, disco ou outro serviço.
Ela é limitada por processamento (CPU-bound) quando a maior parte do tempo é consumida executando cálculos no processador.
A classificação depende do que domina a duração total, e não apenas de existir uma leitura de arquivo ou um laço no código.
Compare a distribuição de tempo nas duas situações.

Em I/O-bound, a espera domina; em CPU-bound, o cálculo domina.
Exemplo
Caso A — consulta remota: para cada pedido, o programa usa 50 ms preparando dados, espera 1,8 s pela resposta de um serviço e usa 30 ms para tratar o retorno. É predominantemente I/O-bound: a espera pela rede domina.
Caso B — análise de imagem local: o programa lê uma imagem em 40 ms e executa 4 s de cálculos sobre seus pixels. É predominantemente CPU-bound: há leitura, mas o cálculo domina.
Dica
Pergunte: “Se eu reduzisse a etapa mais demorada, a duração total cairia bastante?” Essa etapa é a principal evidência para a classificação.
Muitas cargas combinam espera e cálculo. Por exemplo, baixar arquivos, decodificá-los e gerar miniaturas envolve rede, armazenamento e processamento.
Nesses casos, não force um único rótulo para o programa inteiro. Descreva as etapas e identifique qual delas tem maior peso no cenário analisado.
Uma mesma carga pode alternar entre espera e trabalho ativo.

A classificação pode mudar se a duração relativa das etapas mudar.
Relacione cada descrição à classificação mais adequada.
Toque em um item e depois no par correspondente.

Passo 3 de 8
Entenda o que threads compartilham dentro de um processo e por que elas são uma opção para coordenar esperas de entrada e saída.
Uma thread é um fluxo de execução dentro de um processo. Um mesmo processo pode ter mais de uma thread avançando em tarefas diferentes ao longo do tempo.
A consequência central é que as threads do processo usam o mesmo espaço de memória. Portanto, elas podem acessar os mesmos objetos Python — por exemplo, a mesma lista, dicionário ou instância.
Observe que os fluxos são separados, mas os objetos pertencem ao mesmo processo.

Threads distintas podem acessar os mesmos objetos mantidos na memória do processo.
Exemplo
Se uma parte do programa mantém este objeto:
resultados = []As threads desse processo podem receber uma referência para resultados e consultar ou alterar essa mesma lista. Não surge automaticamente uma lista independente para cada thread.
Isso facilita trocar dados sem transportá-los entre memórias separadas. Porém, se mais de uma thread altera um objeto compartilhado, o programa precisa coordenar esses acessos e a biblioteca usada deve ser compatível com esse uso. Esse controle será estudado adiante.
Dica
Memória compartilhada torna o acesso direto possível; ela não garante que alterações simultâneas preservem as regras do seu programa.
Threads são candidatas úteis para coordenar chamadas bloqueantes de bibliotecas síncronas quando a carga é predominantemente de entrada e saída, como rede ou armazenamento.
Enquanto uma thread aguarda uma resposta, outra pode avançar. Isso depende do comportamento da operação e da biblioteca: criar threads, por si só, não transforma qualquer chamada em concorrente nem garante redução do tempo total.
Uma thread fica aguardando uma resposta de rede; outra continua seu trecho de trabalho no mesmo processo.

A espera de I/O de uma thread pode abrir espaço para o progresso de outra.
Verdadeiro ou falso: quando um processo cria várias threads, cada thread recebe automaticamente uma cópia independente de toda lista que já existia no processo.
Verdadeiro ou falso: uma thread aguardando uma operação de rede pode permitir que outra thread do mesmo processo avance.

Passo 4 de 8
Entenda como espaços de memória separados afetam o paralelismo, os dados e os custos de usar processos.
Um processo é uma unidade de execução com seu próprio espaço de memória. Diferentemente das threads de um mesmo processo, processos distintos não acessam diretamente os mesmos objetos Python.
Se dois processos começam a partir de dados parecidos, cada um trabalha sobre sua própria cópia lógica daqueles dados. Alterar uma lista em um processo não atualiza automaticamente a lista do outro.
Observe que a mudança feita pelo Processo A permanece no espaço de memória dele.

Objetos de processos diferentes ficam em espaços de memória separados.
Exemplo
Imagine que o processo principal entregue uma coleção de pedidos a outro processo para cálculo. O trabalhador produz resultados no espaço dele; para o processo principal usá-los, esses resultados precisam voltar por algum meio de comunicação explícito. Não basta o trabalhador alterar uma variável local esperando que ela mude no processo principal.
Processos podem executar trabalho ao mesmo tempo em diferentes núcleos de CPU, se houver núcleos e recursos disponíveis. Isso os torna uma alternativa a avaliar para tarefas de processamento intensivo e suficientemente independentes.
Mas o isolamento tem um preço: entradas precisam ser enviadas ao trabalhador, e resultados precisam ser trazidos de volta. Essa troca não acontece por memória compartilhada automática.
O processo principal distribui partes independentes do trabalho e recebe os resultados para reunir a resposta final.

A comunicação transporta dados entre memórias separadas.
Criar processos consome tempo e memória. Além disso, transportar dados tem custo. Se cada tarefa recebe ou devolve um volume grande de informações, a comunicação pode consumir parte importante do benefício esperado do paralelismo.
Por isso, processos tendem a fazer mais sentido quando o cálculo de cada unidade de trabalho é relevante em comparação com os dados que precisam circular. Se as tarefas dependem intensamente de um estado compartilhado ou exigem trocas frequentes, a coordenação pode ficar cara.
Dica
Antes de escolher processos, pergunte: as partes do trabalho são independentes? Há processamento suficiente em cada parte? Quanto dado precisará ir e voltar entre os processos?
Um programa separa 1.000 imagens em lotes e envia cada lote a processos para aplicar um cálculo pesado. Ao fim, o processo principal precisa reunir os resultados. Qual afirmação é mais adequada?

Passo 5 de 8
Entenda como tarefas cooperam no laço de eventos e reconheça o que impede esse progresso.
O asyncio coordena tarefas por meio de um laço de eventos, normalmente executado em uma única thread. Por isso, ele pode produzir concorrência — avanço alternado de tarefas — sem criar paralelismo de processamento por conta própria.
Quando uma tarefa chega a uma espera compatível com asyncio, ela pode se suspender e devolver o controle ao laço. O laço então deixa outra tarefa pronta avançar. Isso é especialmente útil quando há muitas esperas de entrada e saída, como rede.
Observe que a espera de uma tarefa abre espaço para outra, mas apenas uma executa código na thread do laço em cada instante.

Na espera compatível, a tarefa suspensa cede o controle; isso permite progresso concorrente, não processamento simultâneo.
Exemplo
Espera cooperativa: uma tarefa usa uma API assíncrona compatível para aguardar uma resposta de rede. Enquanto a resposta não chega, o laço pode avançar outras tarefas prontas.
Bloqueio do laço: uma tarefa chama uma função síncrona demorada — por exemplo, uma leitura bloqueante ou um cálculo longo. Essa chamada ocupa a única thread do laço até terminar. Nesse intervalo, as outras tarefas do mesmo laço não avançam.
Colocar uma chamada síncrona dentro de uma tarefa não a transforma em assíncrona. Para aproveitar asyncio diretamente, a biblioteca usada precisa oferecer uma API assíncrona compatível.
Atenção
As tarefas do mesmo laço podem acessar os mesmos objetos do processo. Mesmo sem paralelismo entre elas, uma tarefa pode observar um estado, suspender durante uma espera e encontrar esse estado alterado ao retomar. Regras que dependem de várias etapas ainda exigem coordenação apropriada, assunto que será aprofundado adiante.
Qual diagrama representa uma tarefa aguardando de modo compatível com asyncio, permitindo que outra tarefa do mesmo laço avance?

Passo 6 de 8
Entenda como o GIL e a configuração efetiva do interpretador afetam as expectativas sobre threads.
No CPython com o GIL habilitado, o GIL é um bloqueio do interpretador que restringe a execução de código Python a uma thread por vez dentro do mesmo interpretador.
Isso limita o paralelismo de processamento de código Python entre threads. Ainda assim, várias threads podem fazer progresso concorrente: enquanto uma aguarda uma operação de entrada e saída, outra pode avançar.
Observe a diferença entre alternar o acesso ao interpretador e executar em processos separados.

Com GIL habilitado, threads do mesmo interpretador podem alternar progresso; processos têm interpretadores e espaços de memória separados.
Com o GIL habilitado no CPython, usar várias threads torna automaticamente paralelo o processamento de código Python puro.
Muitas operações de entrada e saída liberam o GIL durante a espera. Algumas extensões nativas também podem liberá-lo e realizar trabalho fora do código Python puro. Portanto, dizer que threads “nunca” executam processamento em paralelo é uma simplificação incorreta.
A expectativa correta depende da operação, da biblioteca e da configuração em uso.
Atenção
O GIL não garante que alterações em objetos compartilhados sejam seguras para a sua aplicação. Uma regra que envolve ler, decidir e alterar estado ainda pode depender da intercalação das threads. A ausência do GIL também não remove a necessidade de coordenação.
Uma aplicação usa threads para fazer várias chamadas de rede por uma biblioteca síncrona adequada ao uso concorrente. Qual conclusão é mais adequada no CPython com GIL habilitado?
Processos separados não disputam um único GIL do mesmo interpretador. Por isso, podem ser candidatos para tarefas independentes e intensivas em código Python quando o GIL está habilitado, considerando os custos de memória e de transportar dados.
Também existem versões e configurações compatíveis com execução sem GIL. Porém, não conclua a configuração apenas pela versão do Python: verifique o interpretador efetivamente usado. Mesmo sem GIL, não há garantia automática de aceleração nem de segurança para estado compartilhado.
Você tem várias tarefas independentes de cálculo intenso em código Python. Justifique por que processos podem ser uma hipótese inicial no CPython com GIL habilitado. Inclua uma cautela sobre desempenho ou compartilhamento de dados.
Escreva pelo menos 100 caracteres (0/100).
Resumo
Saber a versão do Python é suficiente para concluir se threads terão paralelismo de processamento e se o estado compartilhado estará seguro.

Passo 7 de 8
Use uma sequência de decisão para selecionar uma estratégia inicial — ou decidir manter a execução sequencial — considerando gargalo, bibliotecas, estado e custos.
Use esta ordem: 1) identifique a etapa que mais domina o tempo; 2) verifique o tipo de API disponível; 3) considere a configuração do interpretador; 4) avalie estado compartilhado, isolamento e custo de comunicação.
O resultado é uma escolha inicial plausível, não uma promessa de que o programa ficará mais rápido.
A natureza da carga direciona a análise, mas bibliotecas, dados e custos podem alterar a decisão.

Não pule dos termos “I/O” ou “CPU” diretamente para uma ferramenta: os critérios se acumulam.
Exemplo
Um programa consulta muitos serviços HTTP por uma biblioteca síncrona, e cada consulta passa a maior parte do tempo esperando a rede. Se a biblioteca for adequada ao uso concorrente, threads são uma candidata inicial: uma thread que aguarda pode abrir espaço para outra avançar.
Isso não significa que qualquer chamada de rede deva usar threads; considere também os limites do serviço e o estado compartilhado.
Exemplo
Um programa precisa coordenar muitas operações de rede e a biblioteca oferece uma API assíncrona compatível. Asyncio é uma candidata inicial: as tarefas podem cooperar durante esperas compatíveis no laço de eventos.
Não basta a tarefa ser de I/O: uma chamada síncrona demorada no laço bloqueia o avanço das demais.
Exemplo
Cada entrada exige um cálculo longo executado principalmente em código Python, as entradas são independentes e o CPython está com o GIL habilitado. Processos são uma candidata inicial para obter paralelismo de processamento, desde que o custo de iniciar processos e transportar entradas e resultados seja justificável.
Se os dados forem enormes ou as tarefas forem muito curtas, esse transporte pode anular o benefício.
Threads e tarefas do mesmo laço podem acessar os mesmos objetos: isso facilita trocar dados, mas exige coordenação ao alterar estado compartilhado. Processos isolam memória, porém resultados e entradas precisam circular explicitamente.
Em uma carga mista, examine as etapas. Um pipeline pode esperar arquivos na maior parte do tempo e depois realizar uma transformação curta; outro pode ter pouca espera e um cálculo dominante. Escolha pelo gargalo relevante, não por um rótulo único para todo o programa.
Dica
Mantenha a execução sequencial quando as tarefas dependem fortemente umas das outras, quando há pouco tempo de espera ou cálculo para sobrepor, ou quando coordenar dados custa mais do que o possível ganho. Trate concorrência como uma hipótese a validar no cenário real.
Relacione os cenários à estratégia inicial mais justificável.
Toque em um item e depois no par correspondente.

Passo 8 de 8
Aplique os critérios de escolha a cenários concretos, explique os custos envolvidos e identifique quando uma decisão deve ser revista.
Para defender uma escolha, descreva: 1) qual trabalho domina a duração; 2) qual suporte a biblioteca oferece; 3) como os dados precisam circular ou ficar isolados; e 4) qual custo pode anular o benefício.
O resultado não é uma promessa de aceleração. É uma estratégia plausível que ainda precisa ser comprovada no contexto real.
Use este mapa para organizar uma justificativa curta e completa.

A escolha depende da combinação dos critérios, não de uma regra única.
Um programa precisa analisar muitos blocos independentes de dados. Cada bloco passa quase todo o tempo em cálculos executados por código Python. O CPython está com o GIL habilitado, e os resultados de cada bloco são pequenos. Qual é a escolha inicial mais plausível?
Um serviço faz muitas requisições de rede independentes. A biblioteca disponível oferece uma API assíncrona compatível, e cada requisição faz pouco processamento local. Qual é a escolha inicial mais plausível?
Cenário: várias tarefas fazem chamadas por uma biblioteca síncrona de rede; passam a maior parte do tempo esperando respostas e atualizam um pequeno conjunto de objetos em comum. O CPython usa GIL habilitado.
Qual modelo você escolheria inicialmente? Justifique relacionando o gargalo, a biblioteca e o estado compartilhado. Cite também um custo relevante e uma mudança no cenário que faria você reconsiderar a escolha.
Escreva pelo menos 180 caracteres (0/180).
Resumo
Antes de adotar concorrência, formule uma hipótese verificável.
Parabéns! Você concluiu: Escolher entre threads, processos e asyncio
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks