09/03/2026, 16:45 Python vs Rust Async
Sou programador Python aprendendo Rust, tenha ótima
didática e faça correlação entre as linguagens, mostre
como o rust trabalha com Async
Vou te explicar conectando Python asyncio com Rust async / await , e vou me apoiar na
documentação oficial para não te passar nenhum detalhe torto.
Pensou por 21s
Claro. Vamos fazer do jeito certo: comparando Python com Rust, porque isso acelera
muito o aprendizado.
Visão geral
Em Python, async é principalmente uma forma prática de lidar com I/O concorrente
usando asyncio , corrotinas, tasks e um event loop. O loop executa tarefas e callbacks;
quando uma task encontra await , ela é suspensa e o loop pode rodar outra.
Python docume… +2
Em Rust, a ideia também gira em torno de I/O assíncrona, mas o modelo é mais explícito
e mais baixo nível: uma função async retorna um Future, e esse future só avança quando
é pollado por um runtime/executor. O trait Future da biblioteca padrão define isso com
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> .
[Link] +2
A correlação mental mais importante
Pensa assim:
Python async def → cria uma corrotina
Rust async fn → cria um valor que implementa Future
Python await → entrega o controle ao event loop
Rust .await → suspende a execução daquele future até ele estar pronto
Python asyncio.create_task() → agenda uma tarefa no loop
Rust tokio::spawn(...) → agenda uma task no runtime Tokio Python docume… +3
1) Exemplo mínimo: Python vs Rust
[Link] 1/28
09/03/2026, 16:45 Python vs Rust Async
Python
import asyncio
async def buscar_dados():
await [Link](1)
return "ok"
async def main():
resultado = await buscar_dados()
print(resultado)
[Link](main())
Aqui acontece:
1. buscar_dados() é uma corrotina.
2. await [Link](1) pausa essa corrotina.
3. O event loop pode rodar outra coisa nesse intervalo.
4. Depois ela volta e retorna "ok" .
A própria documentação oficial do Python descreve asyncio como base para código
concorrente com async/await . Python docume… +1
Rust
async fn buscar_dados() -> String {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
"ok".to_string()
}
#[tokio::main]
async fn main() {
let resultado = buscar_dados().await;
println!("{}", resultado);
}
Aqui:
1. async fn buscar_dados() não executa imediatamente como função normal.
2. Ela retorna um Future.
3. Quando fazemos .await , o runtime vai dirigindo a execução desse future.
4. tokio::time::sleep(...).await suspende a task sem bloquear a thread do mesmo
jeito “conceitual” que você espera de async. [Link] +2
[Link] 2/28
09/03/2026, 16:45 Python vs Rust Async
2) A grande diferença: em Rust, async é um valor
Essa é a virada de chave.
Em Python
Quando você chama:
coroPython
= buscar_dados()
Executar
você obtém um objeto aguardável/corrotina.
Em Rust
Quando você chama:
let Rust
fut = buscar_dados();
você obtém um future.
A diferença é que em Rust isso é muito central no tipo. O Future é um trait da std, e a
computação assíncrona é representada como um valor que pode estar “pendente” ou
“pronto”. [Link] +1
3) Como o Rust realmente trabalha com async por baixo
Aqui está a parte que costuma confundir quem vem de Python.
Em Python
Você normalmente pensa em:
corrotina
event loop
task
await
Em Rust
Por baixo, o runtime vai chamando poll() no future. O retorno pode ser:
[Link] 3/28
09/03/2026, 16:45 Python vs Rust Async
Poll::Pending → ainda não terminou
Poll::Ready(valor) → terminou e entregou o valor
O contrato oficial do trait Future é exatamente esse. [Link]
Tradução mental
Python
“Essa corrotina pausou no await .”
Rust
“Esse future foi pollado e respondeu Pending ; quando o recurso estiver pronto, o
executor tenta de novo.”
Isso é muito importante porque explica por que o async em Rust é tão eficiente: o runtime
não fica desperdiçando trabalho; ele reativa a task quando ela pode avançar. O Async
Book oficial apresenta exatamente essa visão de futures e execução dirigida por
executor/runtime. [Link].… +2
4) async não significa paralelismo
Isso vale para as duas linguagens.
Python
asyncio faz concorrência cooperativa em um event loop. Enquanto uma task está
rodando, outra task na mesma thread não roda; a troca acontece quando a task encontra
await . Python docume… +1
Rust
Também não é sinônimo de paralelismo. async quer dizer capacidade de suspender sem
bloquear a task, normalmente muito útil para rede, banco, APIs, filas, sockets, arquivos
assíncronos etc. Paralelismo real depende de múltiplas threads e do runtime/configuração.
A documentação do Async Book destaca que .await sozinho executa uma future por vez
dentro daquele fluxo, e para várias futures ao mesmo tempo você usa
composição/execução concorrente. [Link].… +1
5) Concorrência: Python gather vs Rust join!
[Link] 4/28
09/03/2026, 16:45 Python vs Rust Async
Python
import asyncio
async def a():
await [Link](1)
return 10
async def b():
await [Link](2)
return 20
async def main():
r1, r2 = await [Link](a(), b())
print(r1, r2)
Rust
async fn a() -> i32 {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
10
}
async fn b() -> i32 {
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
20
}
#[tokio::main]
async fn main() {
let (r1, r2) = tokio::join!(a(), b());
println!("{r1} {r2}");
}
Correlação direta
[Link](...) lembra bastante join!
ambos esperam múltiplas operações assíncronas
a diferença é que em Rust você sente mais os tipos e o modelo de ownership
A documentação do Async Book trata explicitamente de executar múltiplas futures ao
mesmo tempo, e a std também documenta utilidades relacionadas a join para múltiplas
futures. [Link].… +1
[Link] 5/28
09/03/2026, 16:45 Python vs Rust Async
6) Esperar o primeiro que terminar: Python
wait / FIRST_COMPLETED vs Rust select!
Rust com Tokio
use tokio::sync::oneshot;
#[tokio::main]
async fn main() {
let (tx1, rx1) = oneshot::channel();
let (tx2, rx2) = oneshot::channel();
tokio::spawn(async move {
let _ = [Link]("primeiro");
});
tokio::spawn(async move {
let _ = [Link]("segundo");
});
tokio::select! {
v = rx1 => println!("rx1: {:?}", v),
v = rx2 => println!("rx2: {:?}", v),
}
}
O tokio::select! espera várias operações e segue quando uma delas fica pronta. Isso é
bem parecido, conceitualmente, com esperar o primeiro completado em asyncio .
[Link] +1
7) Spawn de tarefas: muito parecido, mas com exigências
mais fortes em Rust
Python
taskPython
= asyncio.create_task(minha_corrotina())
Executar
Rust
[Link] 6/28
09/03/2026, 16:45 Python vs Rust Async
let handle = tokio::spawn(async {
42
});
Rust
Só que em Rust aparecem exigências extras com frequência, como Send e 'static ,
dependendo de onde a task vai rodar. Isso acontece porque o runtime pode mover a task
entre threads, e Rust precisa garantir segurança de memória e de concorrência em tempo
de compilação. A documentação do Tokio mostra spawn e select! como peças centrais
do runtime assíncrono. [Link] +1
Intuição prática
Em Python você pensa:
“Criei uma task.”
Em Rust você pensa:
“Criei uma task, mas o compilador vai verificar se os dados capturados por ela podem
viver e circular de forma segura.”
Essa é uma das maiores diferenças de ergonomia entre as duas linguagens.
8) Por que existe Pin em Rust async?
Essa é a parte “estranha” para quem vem de Python.
O método poll() do trait Future recebe self: Pin<&mut Self> . A documentação
oficial de std::pin explica que Pin existe para APIs que precisam garantir que certos
valores não sejam movidos na memória depois de fixados; Future::poll é um dos
exemplos principais. [Link] +1
Tradução didática
Em Python, você não pensa nisso.
Em Rust, algumas máquinas de estado geradas por async podem depender de garantias
de posicionamento em memória para serem seguras. Então:
Python esconde esse custo conceitual
Rust expõe parte dele para preservar segurança sem GC e sem custo invisível
[Link] 7/28
09/03/2026, 16:45 Python vs Rust Async
Regra prática para iniciante
Você não precisa dominar Pin no primeiro dia para usar async em Rust.
No início, foque em:
async fn
.await
tokio::spawn
tokio::join!
tokio::select!
Depois você aprofunda Future , Poll , Pin e lifetimes assíncronos.
9) O runtime em Rust: parecido com o event loop, mas
não idêntico
Em Python, você usa [Link](...) e normalmente pensa em “o event loop vai cuidar
de tudo”. Python docume… +1
Em Rust, a linguagem te dá a sintaxe e o trait Future , mas você geralmente usa um
runtime, como Tokio, para:
agendar tasks
timers
sockets assíncronos
utilidades de coordenação
Por isso este padrão é comum:
#[tokio::main]
async fn main() {
// ...
}
Rust
Ou seja: a linguagem fornece o modelo, e o runtime fornece a infraestrutura para
executar esse modelo de forma útil em aplicações reais. O Async Book e o tutorial do
Tokio mostram exatamente essa separação entre futures e executor/runtime.
[Link].… +1
[Link] 8/28
09/03/2026, 16:45 Python vs Rust Async
10) Ownership aparece com força no async Rust
Aqui está um dos choques mais fortes para quem programa Python.
Python
Você compartilha objetos com enorme liberdade.
Rust
No async, você precisa respeitar:
ownership
borrowing
lifetimes
Send / Sync quando houver concorrência entre threads
Exemplo clássico:
let s = String::from("oi");
tokio::spawn(async move {
println!("{s}");
});
R t
O move é muito comum porque a task precisa tomar posse do que usa.
Correlação com Python
Seria como se Python obrigasse você a declarar explicitamente:
“essa task agora é dona desses dados”
Isso parece mais duro no começo, mas é justamente o que evita uma categoria enorme de
bugs de concorrência e memória.
11) Erros comuns de quem vem de Python
Erro 1: achar que async fn executa na hora
Não. Em Rust, async fn retorna um future; ele precisa ser aguardado ou executado por
um runtime. [Link] +1
Erro 2: confundir async com thread
[Link] 9/28
09/03/2026, 16:45 Python vs Rust Async
Async é ótimo para I/O concorrente. CPU pesada normalmente pede outra estratégia,
como threads dedicadas, pools ou offloading.
Erro 3: tentar usar referências emprestadas demais dentro de tasks
Em Python isso passa fácil. Em Rust o compilador barra quando a vida útil dos dados não
é segura.
Erro 4: esquecer que .await pode suspender
Toda vez que há .await , pense:
“a execução pode parar aqui e voltar depois”
Isso afeta locks, borrows e desenho da API.
12) Uma comparação direta lado a lado
Python mental model
async def f():
await algo()
Python Executar
Leitura:
“Tenho uma corrotina; quando chegar no await, o loop pode executar outra task.”
Rust mental model
async fn f() {
algo().await;
}
Rust
Leitura:
“Tenho uma função que produz um future; esse future vira uma máquina de estados;
quando chegar no .await , ele pode retornar Pending e ser retomado depois pelo
executor.”
Esse modelo de “future como máquina de estados” é a forma certa de pensar em async
Rust, alinhada ao Async Book e ao trait Future . [Link].… +2
[Link] 10/28
09/03/2026, 16:45 Python vs Rust Async
13) Exemplo mais realista: várias requisições
Python
import asyncio
async def buscar(id_):
await [Link](1)
return f"dado {id_}"
async def main():
resultados = await [Link](
buscar(1),
buscar(2),
buscar(3),
)
print(resultados)
[Link](main())
Rust
async fn buscar(id: u32) -> String {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
format!("dado {}", id)
}
#[tokio::main]
async fn main() {
let (a, b, c) = tokio::join!(
buscar(1),
buscar(2),
buscar(3),
);
println!("{:?}", vec![a, b, c]);
}
O que aprender daqui
Em Python, o foco fica no fluxo.
Em Rust, o foco fica em:
fluxo
[Link] 11/28
09/03/2026, 16:45 Python vs Rust Async
tipos
ownership
segurança de concorrência
14) Regra prática para pensar como programador Python
migrando para Rust
Use este mapa mental:
Python
“Tenho corrotinas”
“O loop agenda”
“ await cede controle”
“compartilhar objetos é fácil”
Rust
“Tenho futures”
“Um runtime/executor polla futures”
“ .await suspende a task”
“ownership e lifetimes definem o que pode viver e ser movido”
“o compilador garante segurança antes de rodar”
15) O que estudar primeiro em Rust async
A ordem mais inteligente é:
Etapa 1
Aprender a escrever e usar:
async fn
.await
Etapa 2
Aprender runtime com Tokio:
#[tokio::main]
tokio::spawn
tokio::join!
[Link] 12/28
09/03/2026, 16:45 Python vs Rust Async
tokio::select!
Etapa 3
Entender a base:
Future
Poll
Pin
Etapa 4
Dominar problemas reais:
Arc
Mutex assíncrono
canais
cancelamento
tratamento de erro
16) Resumo em uma frase
Python async te faz pensar em corrotinas e event loop.
Rust async te faz pensar em futures, máquina de estados, executor e ownership.
Python docume… +2
17) Exemplo final: a tradução mais fiel entre as linguagens
Python
import asyncio
async def trabalho(nome, atraso):
print(f"início {nome}")
await [Link](atraso)
print(f"fim {nome}")
return nome
async def main():
t1 = asyncio.create_task(trabalho("A", 2))
t2 = asyncio.create_task(trabalho("B", 1))
[Link] 13/28
09/03/2026, 16:45 Python vs Rust Async
r1 = await t1
r2 = await t2
print(r1, r2)
[Link](main())
Rust
use tokio::task::JoinHandle;
use std::time::Duration;
async fn trabalho(nome: &'static str, atraso: u64) -> &'static str {
println!("início {}", nome);
tokio::time::sleep(Duration::from_secs(atraso)).await;
println!("fim {}", nome);
nome
}
#[tokio::main]
async fn main() {
let t1: JoinHandle<&'static str> = tokio::spawn(async {
trabalho("A", 2).await
});
let t2: JoinHandle<&'static str> = tokio::spawn(async {
trabalho("B", 1).await
});
let r1 = [Link]();
let r2 = [Link]();
println!("{} {}", r1, r2);
}
O que esse exemplo ensina
asyncio.create_task() ↔ tokio::spawn(...)
await task ↔ [Link]
em Rust, o compilador participa muito mais da segurança do fluxo
Fechamento direto
Para alguém que já programa em Python, o jeito mais rápido de aprender async em Rust é
não tentar decorar teoria primeiro.
[Link] 14/28
09/03/2026, 16:45 Python vs Rust Async
Faça esta tradução mental sempre:
corrotina Python → future Rust
event loop → runtime/executor
await → ponto de suspensão
objeto compartilhado livremente → ownership/borrowing verificado pelo
compilador
Esse é o coração do assunto.
No próximo passo, eu posso te montar um guia progressivo com 5 exemplos, começando
em asyncio e reescrevendo um por um em Rust com Tokio, incluindo:
HTTP, tarefas concorrentes, canais, mutex assíncrono e tratamento de erro.
Fontes
#\[tokio::main\]
Fale agora sobre concorrência real, Threads, Paralelismo,
Channels (comunicação entre threads)
Agora eu vou conectar concorrência real em Rust com a sua base de Python, separando
bem async, threads e paralelismo, porque misturar esses três conceitos atrapalha muito
no começo.
Pensou por 12s
Perfeito. Agora entramos no ponto em que muita gente mistura tudo: async, concorrência
real, threads e paralelismo.
Vou organizar isso como um professor faria no quadro, ligando sempre com Python.
1) Primeiro: separar os conceitos corretamente
Async
async não é thread.
No ecossistema Rust com Tokio, #[tokio::main] cria e inicializa um runtime assíncrono
para executar tarefas assíncronas; o runtime contém o agendador de tasks, I/O orientada a
[Link] 15/28
09/03/2026, 16:45 Python vs Rust Async
eventos, timers etc. A própria documentação do Tokio explica que essa macro transforma
async fn main() em uma fn main() síncrona que cria o runtime e executa a função
assíncrona. [Link] +1
Concorrência
Concorrência é quando várias tarefas progridem no mesmo intervalo de tempo, mesmo
que não executem literalmente ao mesmo tempo o tempo todo.
Paralelismo
Paralelismo é quando duas ou mais coisas realmente executam ao mesmo tempo, em
mais de um núcleo/thread.
Thread
Thread é a unidade de execução do sistema operacional usada para trabalho simultâneo
real. Em Rust, a biblioteca padrão tem o módulo std::thread para isso. A documentação
da std diz explicitamente que o módulo thread contém as abstrações de threading de
Rust. [Link]
2) Comparando com Python
Python
Você já deve conhecer algo assim:
asyncio → concorrência cooperativa para I/O
threading → threads reais
multiprocessing → paralelismo real sem briga com GIL para CPU-bound
Rust
Em Rust, a divisão mental correta é:
async /Tokio → excelente para I/O concorrente
std::thread → threads reais
múltiplas threads em múltiplos núcleos → paralelismo real
channels , Mutex , Arc , atomics → comunicação e sincronização entre threads/tasks
A diferença grande é que Rust não te “esconde” segurança de concorrência. O compilador
participa do processo.
[Link] 16/28
09/03/2026, 16:45 Python vs Rust Async
3) O que #[tokio::main] faz de verdade
Como você pediu correlação com isso especificamente, vamos focar.
Quando você escreve:
#[tokio::main]
async fn main() {
// ...
}
Rust
isso não significa “agora tudo virou multithread automaticamente no sentido conceitual
que iniciantes imaginam”.
O que significa é:
1. o Tokio cria um runtime;
2. esse runtime passa a executar as suas tasks assíncronas;
3. o runtime pode ser configurado, e a macro #[tokio::main] é a forma simples de
iniciar isso. [Link] +1
A documentação do tokio::main também diz que a macro fornece configuração básica e
que, para controle maior, você usa tokio::runtime . [Link] +1
Tradução para quem vem de Python
Pense assim:
[Link](main()) em Python
#[tokio::main] async fn main() em Rust
Ambos entram em um contexto assíncrono, mas isso ainda não é a mesma coisa que criar
threads manualmente.
4) Concorrência cooperativa vs concorrência real com
threads
Async/Tokio
No async, várias tasks podem avançar de forma concorrente. Isso é ótimo para:
sockets
HTTP
[Link] 17/28
09/03/2026, 16:45 Python vs Rust Async
banco de dados
filas
timers
servidores web
Tokio descreve seu modelo como plataforma de I/O não bloqueante e orientada a
eventos, com runtime, tasks, sincronização e canais. [Link] +1
Intuição
Uma task roda até encontrar .await .
Quando ela espera algo externo, o runtime pode rodar outra task.
Isso é muito parecido com Python asyncio .
Threads reais
Quando você usa std::thread::spawn , você cria uma thread real do sistema operacional.
Exemplo:
use std::thread;
fn main() {
let handle = thread::spawn(|| {
println!("Rodando em outra thread");
});
[Link]().unwrap();
}
Aqui não é “simulação cooperativa”. É thread de verdade.
Comparação com Python
Isso é análogo a [Link](...) , só que em Rust você entra muito mais cedo em:
ownership
move
compartilhamento seguro
ausência de data race em código seguro
[Link] 18/28
09/03/2026, 16:45 Python vs Rust Async
5) Concorrência real e paralelismo: onde está a diferença
prática?
Concorrência
Você pode ter 10 tarefas competindo por progresso.
Paralelismo
Você pode ter 4 dessas tarefas rodando realmente ao mesmo tempo em 4 núcleos.
Em Rust
Se você tem várias threads, o SO pode escaloná-las em vários núcleos, dando paralelismo
real.
Em async
Você pode ter muitas tasks concorrentes, mas isso não implica automaticamente que
todas estão rodando em paralelo naquele instante.
6) Quando usar async e quando usar thread
Essa regra prática ajuda demais.
Use async quando o trabalho é I/O-bound
Exemplos:
esperar resposta HTTP
esperar query no banco
servidor TCP
WebSocket
fila de mensagens
timeout, sleep, backoff
Use threads quando o trabalho é CPU-bound ou bloqueante
Exemplos:
compressão
parsing pesado
processamento de imagem
simulação
criptografia pesada
[Link] 19/28
09/03/2026, 16:45 Python vs Rust Async
loops matemáticos pesados
biblioteca bloqueante
Tradução mental Python → Rust
asyncio → tokio
threading → std::thread
trabalho pesado que não deve travar o fluxo → thread separada ou estratégia de
offload
7) O modelo mais idiomático em Rust: message passing
Rust gosta muito de uma ideia: “não compartilhe memória se você puder trocar
mensagens”.
A documentação do livro de Rust apresenta channels exatamente como mecanismo de
message passing, e a std fornece std::sync::mpsc , onde mpsc significa multiple
producer, single consumer. [Link] +1
8) Channels entre threads
O que é um channel?
É um “cano” de comunicação:
um lado envia ( Sender )
o outro recebe ( Receiver )
A std documenta channel() como um canal assíncrono no sentido de envio não
bloqueante para o remetente com buffer “infinito” conceitual, enquanto recv() bloqueia
até receber algo ou até todos os senders serem fechados. [Link]
Exemplo simples
Rust
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
[Link] 20/28
09/03/2026, 16:45 Python vs Rust Async
let msg = String::from("olá da thread");
[Link](msg).unwrap();
});
let recebido = [Link]().unwrap();
println!("Recebido: {}", recebido);
}
O que aconteceu aqui
1. mpsc::channel() criou o canal.
2. tx é o transmissor.
3. rx é o receptor.
4. A thread filha envia a mensagem.
5. A thread principal recebe com recv() .
9) Correlação com Python
Em Python, você pode pensar em algo próximo de:
[Link]
[Link]
[Link] no mundo async
Mas em Rust o canal entra com um peso maior na arquitetura porque ele combina muito
bem com:
ownership
ausência de data race
desacoplamento entre threads
10) mpsc : múltiplos produtores, um consumidor
A std deixa isso claro: o Sender pode ser clonado, mas o Receiver é único.
[Link] +1
Exemplo
Rust
use std::sync::mpsc;
use std::thread;
[Link] 21/28
09/03/2026, 16:45 Python vs Rust Async
fn main() {
let (tx, rx) = mpsc::channel();
for i in 0..3 {
let tx_clone = [Link]();
thread::spawn(move || {
tx_clone.send(format!("mensagem da thread {}", i)).unwrap();
});
}
drop(tx);
for msg in rx {
println!("{}", msg);
}
}
ChatGPT 5.4 Thinking Memória desativada
Didática importante
O drop(tx) da thread principal é importante aqui porque, se ainda existir algum Sender
vivo, o receptor pode continuar esperando mais mensagens.
11) Canais síncronos e backpressure
Além de channel() , existe sync_channel() na std.
A documentação oficial explica que sync_channel(bound) cria um canal limitado; quando
o buffer enche, send passa a bloquear. [Link]
Exemplo
Rust
use std::sync::mpsc::sync_channel;
use std::thread;
fn main() {
let (tx, rx) = sync_channel(2);
thread::spawn(move || {
[Link](10).unwrap();
[Link](20).unwrap();
[Link](30).unwrap(); // pode bloquear até alguém consumir
});
println!("{}", [Link]().unwrap());
println!("{}", [Link]().unwrap());
[Link] 22/28
09/03/2026, 16:45 Python vs Rust Async
println!("{}", [Link]().unwrap());
}
Por que isso é útil?
Porque você controla pressão do sistema.
Em termos práticos
Se produtor está muito mais rápido que consumidor, canal ilimitado pode crescer demais.
Com buffer limitado, você cria backpressure.
12) Comunicação por mensagem vs memória
compartilhada
Existem dois estilos clássicos:
Estilo 1 — Message passing
Você usa channel .
Cada thread faz seu trabalho e envia resultados.
Estilo 2 — Shared state
Você compartilha dados com Arc<Mutex<T>> .
Rust favorece bastante o primeiro quando possível. Tokio inclusive diz que, em programas
Tokio, a forma mais comum de sincronização é message passing, com a vantagem de
evitar estado compartilhado. [Link]
13) Exemplo com memória compartilhada
Rust
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let contador = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let contador = Arc::clone(&contador);
[Link] 23/28
09/03/2026, 16:45 Python vs Rust Async
let handle = thread::spawn(move || {
let mut num = [Link]().unwrap();
*num += 1;
});
[Link](handle);
}
for h in handles {
[Link]().unwrap();
}
println!("Resultado: {}", *[Link]().unwrap());
}
Como pensar nisso vindo de Python
Seria como compartilhar um inteiro mutável entre threads com lock.
Mas em Rust você precisa declarar explicitamente:
Arc → posse compartilhada entre threads
Mutex → exclusão mútua
lock() → entrada na região crítica
14) Message passing vs Mutex: quando usar cada um?
Use channel quando:
quer desacoplar produtor e consumidor
quer pipeline
quer workers independentes
quer evitar estado compartilhado
Use Arc<Mutex<T>> quando:
várias threads precisam acessar o mesmo estado mutável
esse estado realmente precisa ser centralizado
Regra de ouro
Se você consegue resolver com mensagens, isso costuma simplificar o raciocínio.
15) Como isso conversa com Tokio
[Link] 24/28
09/03/2026, 16:45 Python vs Rust Async
No mundo Tokio, além de threads da std, você também tem canais assíncronos e
primitivas de sincronização próprias do runtime. A documentação de tokio::sync
destaca message passing como forma comum de sincronização em programas Tokio.
[Link]
Então há dois mundos:
Mundo sync / threads da std
std::thread
std::sync::mpsc
std::sync::Mutex
Mundo async / Tokio
tokio::spawn
tokio::sync::*
canais async
tokio::select!
Não é proibido misturar, mas precisa saber exatamente o que está fazendo.
16) Um erro muito comum de iniciante
Misturar esta ideia errada:
“Se eu usei #[tokio::main] , então tudo agora é paralelo.”
Não.
O que você ganhou foi um runtime assíncrono. Ele agenda tasks assíncronas, fornece
timers e I/O assíncrona. [Link] +1
Paralelismo real depende de execução em múltiplas threads/núcleos.
17) Outro erro comum: achar que channel é só para async
Também não.
Channels existem muito fortemente no mundo de threads da std. O módulo
std::sync::mpsc é justamente sobre isso. [Link] +1
[Link] 25/28
09/03/2026, 16:45 Python vs Rust Async
18) Fluxo mental correto para um programador Python
Aqui vai a tradução mais útil.
Em Python você costuma pensar:
“Vou usar asyncio para rede”
“Vou usar threading para rodar em paralelo”
“Vou usar queue para comunicação”
Em Rust pense assim:
“Vou usar Tokio para I/O assíncrona”
“Vou usar std::thread para threads reais”
“Vou usar mpsc ou canais async para comunicação”
“Vou usar Arc<Mutex<T>> só quando estado compartilhado for realmente necessário”
19) Exemplo completo com workers e channel
Esse exemplo já é bem prático.
Rust
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
for i in 0..4 {
let tx = [Link]();
thread::spawn(move || {
let resultado = i * i;
[Link]((i, resultado)).unwrap();
});
}
drop(tx);
for (entrada, resultado) in rx {
println!("{}^2 = {}", entrada, resultado);
}
}
O que isso ensina
4 threads reais
[Link] 26/28
09/03/2026, 16:45 Python vs Rust Async
cada thread calcula algo
cada uma manda o resultado pelo canal
a thread principal coleta tudo
Esse padrão é excelente para:
worker pool simples
fan-out / fan-in
processamento paralelo de tarefas independentes
20) Sobre crossbeam
Embora a std ofereça std::sync::mpsc , a documentação do crossbeam::channel o
apresenta como alternativa com mais recursos e melhor desempenho. [Link]
Então, em projetos reais, muita gente usa:
std::sync::mpsc para aprender e casos simples
crossbeam::channel para cenários mais fortes
21) Resumo direto e correto
#[tokio::main]
Cria um runtime assíncrono e executa sua async fn main , não é sinônimo automático de
“threads manuais” nem de “paralelismo mágico”. [Link] +1
std::thread
É thread real do sistema operacional. [Link]
Paralelismo
Acontece quando múltiplas threads realmente executam ao mesmo tempo em múltiplos
núcleos.
std::sync::mpsc
É o canal padrão da std para message passing entre threads; mpsc significa múltiplos
produtores e um consumidor. channel() é não bloqueante no envio e sync_channel() é
limitado e pode bloquear no send . [Link] +2
[Link] 27/28
09/03/2026, 16:45 Python vs Rust Async
Padrão idiomático
Sempre que der, prefira troca de mensagens a estado compartilhado. Tokio destaca
message passing como forma comum de sincronização por evitar shared state. [Link]
22) Mapa mental final
Python
asyncio → I/O concorrente
threading → threads
queue → comunicação
multiprocessing → CPU pesado / paralelismo sem GIL
Rust
tokio → I/O concorrente async
std::thread → threads reais
mpsc / crossbeam → comunicação entre threads
Arc<Mutex<T>> → estado compartilhado quando necessário
No próximo passo, eu posso te mostrar 3 exemplos lado a lado em Python e Rust:
1. worker pool com threads,
2. pipeline com channels,
3. versão async com Tokio,
para você enxergar exatamente quando usar cada modelo.
Fontes
[Link] 28/28